8

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

我们已经实现了 Django 的 REST 框架并遇到了这个问题。对于诸如“AccountUser”之类的记录,我只想更改名称字段,因此我发送以下请求:PATCH /api/users/1/ HTTP/1.1 Host: localhost X-CSRFToken: 111122223333444455556666 Content-Type: application/json ;charset=UTF-8 缓存控制:无缓存

{ "fullname": "John Doe" }

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

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
4

5 回答 5

1

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

只有其他想法是,即使您列出的示例仅显示发送 字段,您也可能会发送一个触发验证错误的account(like ) 值。nullfullname

于 2013-10-19T01:19:20.917 回答
1

请参阅我关于部分更新的回答。您还可以查看 drf docs和 this one docs

于 2016-07-12T14:52:06.427 回答
0

我来到这里是因为我遇到了类似的问题。CREATE 很好,但 PATCH 不是。

由于 OP 没有发布 ViewSets,如果他使用自定义 ViewSets,我会暂停,我在覆盖更新功能时出错:

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)
于 2018-09-14T09:41:05.700 回答
0

就我而言,我所要做的就是添加required=False到我的序列化器字段的参数中。

可以肯定的是一个新手错误,但我想我会在这里提到它,以防它帮助任何人。

于 2021-03-04T05:50:53.967 回答
0

您可以在 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}
        }
于 2021-06-14T05:24:17.897 回答