Python Django REST框架修补程序在必填字段上失败

Python Django REST框架修补程序在必填字段上失败,python,django,rest,django-rest-framework,Python,Django,Rest,Django Rest Framework,我们正在创建一个API,它需要允许用户更新记录。在许多情况下,如状态更新或名称更改,只有一个字段会更改。对于补丁请求,这似乎是一个合适的用例场景。据我所知,这是一个“部分”更新 我们已经实现了Django的REST框架,并遇到了这个问题。对于“AccountUser”之类的记录,我只想更改名称字段,以便发送以下请求: PATCH/api/users/1/HTTP/1.1 主机:本地主机 X-CSRFToken:11112222333344445556666 内容类型:application/js

我们正在创建一个API,它需要允许用户更新记录。在许多情况下,如状态更新或名称更改,只有一个字段会更改。对于补丁请求,这似乎是一个合适的用例场景。据我所知,这是一个“部分”更新

我们已经实现了Django的REST框架,并遇到了这个问题。对于“AccountUser”之类的记录,我只想更改名称字段,以便发送以下请求: PATCH/api/users/1/HTTP/1.1 主机:本地主机 X-CSRFToken:11112222333344445556666 内容类型:application/json;字符集=UTF-8 缓存控制:没有缓存

{ "fullname": "John Doe" }
该记录显然具有其他属性,包括两个“相关”字段,如新记录所需的“account”。提交请求时,响应为400错误,正文如下: {“帐户”:[“此字段是必需的。”]} 用户的序列化程序如下所示:

class AccountUserSerializer(serializers.ModelSerializer):
    account = serializers.PrimaryKeyRelatedField()

class Meta:
    model = AccountUser
    fields = ('id', 'account', 'fullname', ... )
    depth = 1
class AccountUser(models.Model):
    ''' Account User'''
    fullname = models.CharField(max_length=200,
        null=True,blank=True)
    account = models.ForeignKey(Account,
        on_delete=models.PROTECT
        )

    objects = AccountUserManager()

    def __unicode__(self):
        return self.email

    class Meta:
        db_table = 'accounts_account_user'
模型如下所示:

class AccountUserSerializer(serializers.ModelSerializer):
    account = serializers.PrimaryKeyRelatedField()

class Meta:
    model = AccountUser
    fields = ('id', 'account', 'fullname', ... )
    depth = 1
class AccountUser(models.Model):
    ''' Account User'''
    fullname = models.CharField(max_length=200,
        null=True,blank=True)
    account = models.ForeignKey(Account,
        on_delete=models.PROTECT
        )

    objects = AccountUserManager()

    def __unicode__(self):
        return self.email

    class Meta:
        db_table = 'accounts_account_user'
我在这里是做错了什么,还是期望能够以这种方式更新记录上的单个字段是错误的。谢谢这个社区太棒了

编辑: 已请求-AccountUserManager:

class AccountUserManager(BaseUserManager):

    def create_user(self, email, account_name):
        username = hash_email_into_username(email)
        ...
        account = Account.objects.get(name=account_name)
        account_user = AccountUser(email=email,user=user,account=account)
        account_user.save()
        return account_user

看起来你的经理没有过滤用户。我鼓励您使用pdb并在视图代码中设置断点,然后逐步了解它为什么试图创建新记录。我可以保证,我们一直使用补丁来完成部分更新,并且只发送几个字段来更新,没有问题


唯一的另一个想法是,您正在为触发验证错误的
account
(如
null
)发送一个值,即使您列出的示例仅显示发送
fullname
字段。

请参阅我的关于部分更新。您还可以看到drf和这个

我来这里是因为我遇到了类似的问题。创建是好的,但补丁不是

因为OP不发布视图集,如果他使用自定义视图集,我会挂起,这是我在重写更新函数时犯的错误:

class MyViewSet(ModelViewSet):
    def update(self, request, *args, **kwargs):
        // Do some checking
        return super().update(request, args, kwargs)
我的错误是调用
super()
。缺少星号。这可以解决我的问题

        return super().update(request, *args, **kwargs)

在我的例子中,我所要做的就是将
required=False
添加到序列化程序字段的参数中


这确实是一个新手的错误,但我想我应该在这里提到它,以防它对任何人都有帮助。

您只需在serializers.py中的fields变量后添加这一行即可

class AccountUserSerializer(serializers.ModelSerializer):
    account = serializers.PrimaryKeyRelatedField()

class Meta:
    model = AccountUser
    fields = ('id', 'account', 'fullname', ... )
    depth = 1
    extra_kwargs = {
            'account' : {'required' : False}
        }

尝试在
模型中添加一个
相关的\u name='account'
。ForeignKey(account,…
仅用于
帐户
模型的反向查找。你能发布你的
帐户用户管理器
吗?我猜问题是管理器没有在
pk=1
返回对象,因此你的补丁调用(调用
partial\u update
)认为需要创建一个新实例。