How to PATCH a single field using Django Rest Framework? How to PATCH a single field using Django Rest Framework? python python

How to PATCH a single field using Django Rest Framework?


Serializers allow partial updates by specifying partial=True when initializing the serialzer. This is how PATCH requests are handled by default in the generic views.

serializer = CommentSerializer(comment, data=request.data, partial=True)

This will allow you to update individual fields in a serializer, or all of the fields if you want, without any of the restrictions of a standard PUT request.


As Kevin Brown stated you could use the partial=True, which chefarov clarified nicely.

I would just like to correct them and say you could use generics freely, depending on the HTTP method you are using:

  • If you are using PATCH HTTP method like asked, you get it out of the box. You can see UpdateModelMixin code for partial_update:

    def partial_update(self, request, *args, **kwargs):    kwargs['partial'] = True    return self.update(request, *args, **kwargs)
  • For any HTTP method different from PATCH, this can be accomplished by just overriding the get_serializer method as follows:

    def get_serializer(self, *args, **kwargs):    kwargs['partial'] = True    return super(YOUR_CLASS, self).get_serializer(*args, **kwargs)

This will create the serializer as partial, and the rest of the generics will work like a charm without any manual intervention in the update/partial_update mechanism.

Under the hood

I used the generic: generics.UpdateAPIView which uses the UpdateModelMixin which has this code:

def update(self, request, *args, **kwargs):    partial = kwargs.pop('partial', False)    instance = self.get_object()    serializer = self.get_serializer(instance, data=request.data, partial=partial)    …

So, if you override the get_serializer function, you can actually override the partial argument and force it to be true.

Please note, that if you want it partial only for some of the HTTP methods, this makes this approach more difficult.

I am using djangorestframework==3.5.3


It does seem to be supported out of the box. On your browser API, navigate to a model detail page, at the bottom next to the HTML Form tab click Raw data, delete everything from the JSON string except the ID field and the field you wish to change, and click PATCH. A partial PATCH update is performed.

I'm using djangorestframework==3.2.4, and haven't had to do anything to my ViewSets and Serializers to enable this.

In this exampe we are updating the bool status_field field of the model, and I'm using jquery 2.2.1. Add the following to the <head>:

<script src="{% static 'my_app/jquery.min.js' %}"></script><script>$(document).ready(function(){    var chk_status_field = $('#status_field');    chk_status_field.click(function(){        $.ajax({url: "{% url 'model-detail' your_rendering_context.id %}",            type: 'PATCH', timeout: 3000, data: { status_field: this.checked }        })        .fail(function(){            alert('Error updating this model instance.');            chk_status_field.prop('checked', !chk_status_field.prop('checked'));        });    });});</script>

Then in a <form>:

<input type="checkbox" id="status_field" {% if your_rendering_context.status_field %}     checked {% endif %} >

I chose to permit the checkbox to change, then revert it in the case of failure. But you could replace click with mousedown to only update the checkbox value once the AJAX call has succeeded. I think this will lead to people repeatedly clicking the checkbox for slow connections though.