Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST Framework PATCH fails on required fields

We are creating an API that needs to allow a user to update a record. In many cases, like a status update or name change, only one field will change. This seems an appropriate use-case scenario for a PATCH request. As I understand it this is a 'partial' update.

We've implemented Django's REST Framework and run into this issue. For a record such as a "AccountUser" I want to change a name field only so I send the following request: PATCH /api/users/1/ HTTP/1.1 Host: localhost X-CSRFToken: 111122223333444455556666 Content-Type: application/json;charset=UTF-8 Cache-Control: no-cache

{ "fullname": "John Doe" }

The record obviously has other attributes including a couple of 'related' fields such as 'account' which is required for a new record. When submit the request, the response is a 400 error with the following body: { "account": [ "This field is required." ] } The serializer for the user looks like this:

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

class Meta:
    model = AccountUser
    fields = ('id', 'account', 'fullname', ... )
    depth = 1

And the model looks like this:

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'

Am I doing something wrong here or is it wrong to expect to be able to update a single field on a record this way. Thanks! This community rocks!

EDIT: Requested - 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
like image 960
gkl Avatar asked Oct 18 '13 16:10

gkl


People also ask

What is difference between put and patch in Django REST framework?

PATCH HTTP Request: Unlike PUT Request, PATCH does partial update e.g. Fields that need to be updated by the client, only that field is updated without modifying the other field. So in the previous example, we have to send only the name and email field in the request body.

Does Django require rest framework?

Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs. Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django.

How to raise custom exception in django rest framework?

Custom exception handlingThe exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.

What is HyperlinkedModelSerializer in Django?

HyperlinkedModelSerializer is a layer of abstraction over the default serializer that allows to quickly create a serializer for a model in Django. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds.


2 Answers

It doesn't look like your manager is filtering the user. I'd encourage you to use pdb and set a breakpoint in your view code and step through to see why its attempting to create a new record. I can vouch that we use PATCH to complete partial updates all the time and only send a few fields to update without issue.

Only other thought is that you're some how sending a value for account (like null) that's triggering the validation error even though you're listed example only shows sending the fullname field.

like image 176
Kevin Stone Avatar answered Oct 29 '22 15:10

Kevin Stone


See my answer about partial updates. Also you can see the drf docs and this one docs

like image 37
M.Void Avatar answered Oct 29 '22 15:10

M.Void