Django rest框架序列化程序忽略额外的_kwargs或自定义属性

Django rest框架序列化程序忽略额外的_kwargs或自定义属性,django,django-rest-framework,django-serializer,Django,Django Rest Framework,Django Serializer,我正在尝试制作一个api,它对于客户端和主用户来说略有不同。因此,如果角色是客户机,我想稍后添加客户机 class StoreSerializer(serializers.ModelSerializer): class Meta: model = models.Store fields = ["id", "name", "location", "location_lat", "location_lng", "client"] def create

我正在尝试制作一个api,它对于客户端和主用户来说略有不同。因此,如果角色是客户机,我想稍后添加客户机

class StoreSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Store
        fields = ["id", "name", "location", "location_lat", "location_lng", "client"]

    def create(self, validated_data):
        user = self.context["request"].user
        if user.role == Roles.CLIENT.name:
            validated_data["client"] = user.client
这个哑巴模型看起来像这样

class Store(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
现在,当我使用具有角色客户端的用户调用序列化程序时,我得到以下响应:

{"client":["This field is required."]}
这是正确的。但是当我向StoreSerializer添加
extra_kwargs
时,奇怪的事情发生了。如果我将序列化程序更改为:

class StoreSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Store
        fields = ["id", "name", "location", "location_lat", "location_lng", "client"]
        extra_kwargs = {
            "client": { "required": False }
        }

    def create(self, validated_data):
        user = self.context["request"].user
        if user.role == Roles.CLIENT.name:
            validated_data["client"] = user.client
或者改成

class StoreSerializer(serializers.ModelSerializer):
    client = serializers.UUIDField(required=False)

    class Meta:
        model = models.Store
        fields = ["id", "name", "location", "location_lat", "location_lng", "client"]

    def create(self, validated_data):
        user = self.context["request"].user
        if user.role == Roles.CLIENT.name:
            validated_data["client"] = user.client
我得到了同样的回答。这怎么可能?客户不应该被要求,对吗

版本:

  • Django:2.2.3
  • Django rest框架:3.9.4

如果你说的是对的,那么我会跳出这个领域。无论如何,这可能是最好的,这样当用户未经授权时,API资源管理器就不会包含它

class StoreSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Store
        fields = ["id", "name", "location", "location_lat", "location_lng", "client"]

    def __init__(*args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.context["request"].user.role == Roles.CLIENT.name:
            del self.fields["client"]

    def create(self, validated_data):
        user = self.context["request"].user
        if user.role == Roles.CLIENT.name:
            validated_data["client"] = user.client

商店模型应如下:(注意
空白

现在在DB级别上,您允许客户机在存储模型中为空

以这种方式序列化程序:

class StoreSerializer(serializers.ModelSerializer):
    client = serializers.PrimaryKeyRelatedField(queryset=models.Client.objects.all(), required=False)

    class Meta:
        model = models.Store
        fields = ["id", "name", "client"]
    ...

您的序列化程序现在应该可以工作了。

您是否尝试将客户端外键设置为允许null和blank?是的,但仅在序列化程序中。我没有在模型中尝试。但是很明显,我不希望当你发出这些请求时,客户端是否被设置为任何东西,或者user.role是否等于Roles.client?在我的情况下,要么用户是客户端,这意味着用户模型具有客户端属性。如果用户没有客户端角色,则表示他已将请求与客户端一起发送。如果这有道理的话?不能复制。这是哪个DRF版本?另外,请在后两种情况下添加整个
StoreSerializer
定义,以及您正在传递的
数据的示例。当该字段初始化为
required=False
或在
extra_-kwargs
中提及时,该字段不应提出此类投诉。完全删除该字段在任何方面都不会为根本原因服务。一致认为它不应该以这种方式工作,但绝对同意它不能解决他们的问题。如果无法填充客户端的用户浏览到可浏览的API,他们甚至不应该看到选择客户端的选项。实现这一目标的唯一方法是删除字段。
class StoreSerializer(serializers.ModelSerializer):
    client = serializers.PrimaryKeyRelatedField(queryset=models.Client.objects.all(), required=False)

    class Meta:
        model = models.Store
        fields = ["id", "name", "client"]
    ...