I'm trying to implement partial_update
with Django Rest Framework but I need some clarification because I'm stuck.
Why do we need to specify partial=True?
In my understanding, we could easily update Demo object inside ofpartial_update
method. What is the purpose of this?What is inside of serialized variable?
What is inside ofserialized
variable inpartial_update
method? Is that a Demo object? What function is called behind the scenes?- How would one finish the implementation here?
Viewset
class DemoViewSet(viewsets.ModelViewSet):
serializer_class = DemoSerializer
def partial_update(self, request, pk=None):
serialized = DemoSerializer(request.user, data=request.data, partial=True)
return Response(status=status.HTTP_202_ACCEPTED)
Serializer
class DemoSerializer(serializers.ModelSerializer):
class Meta:
model = Demo
fields = '__all__'
def update(self, instance, validated_data):
print 'this - here'
demo = Demo.objects.get(pk=instance.id)
Demo.objects.filter(pk=instance.id)\
.update(**validated_data)
return demo
I have the same questions as yours before, but when I dig into the source code of rest_framework, I got the following findings, hope it would help:
For question 1)
This question is related to HTTP verbs.
PUT: The PUT method replaces all current representations of the target resource with the request payload.
PATCH: The PATCH method is used to apply partial modifications to a resource.
Generally speaking,
partial
is used to check whether the fields in the model is needed to do field validation when client submitting data to the view.For example, we have a
Book
model like this, pls note both of thename
andauthor_name
fields are mandatory (not null & not blank).For some scenarios, We may only need to update part of the fields in the model, e.g., we only need to update
name
field in theBook
. So for this case, client will only submit thename
field with new value to the view. The data submit from the client may look like this:But you may have notice that our model definition does not allow
author_name
to be blank. So we have to usepartial_update
instead ofupdate
. So the rest framework will not perform field validation check for the fields which is missing in the request data.For testing purpose, you can create two views for both
update
andpartial_update
, and you will get more understanding what I just said.Example:
views.py urls.pyData to submit
When you submit the above json to the
/book/update/1/
, you will got the following error with HTTP_STATUS_CODE=400:But when you submit the above json to
/book/update-partial/1/
, you will got HTTP_STATUS_CODE=200 with following response,For question 2)
serialized
is a object wrapping the model instance as a serialisable object. and you can use this serialized to generate a plain JSON string withserialized.data
.For question 3)
I think you can answer yourself when you have read the answer above, and you should have known when to use
update
and when to usedpartial_update
.If you still have any question, feel free to ask. I just read part of the source odes of rest framework, and may have not understand very deeply for some terms, and please point it out when it is wrong...
You forgot
serializer.save()
You can finish it the following way . . .
Also, you shouldn't need to override the update method in the serializer.
I had an issue where my multi-attribute/field validation in a rest_framework serializer was working with a POST /resources/ request but failing with a PATCH /resources/ request. It failed in the PATCH case because it was only looking for values in the supplied
attrs
dict and not falling back to values inself.instance
. Adding a methodget_attr_or_default
to do that fallback seems to have worked:Just a quick note as it seems that nobody has already pointed this out:
The first argument of DemoSerializer should be a Demo instance, not a user (at least if you use DRF 3.6.2 like me).
I don't know what you are trying to do, but this is a working example:
I do the partial update and then I do other things calling my_func and passing the current user and the demo instance already updated.
Hope this helps.
For partial update - PATCH http method
For full update - PUT http method
When doing an update with DRF, you are supposed to send request data that includes values for all (required) fields. This is at least the case when the request is via the PUT http method. From what I understand, you want to update one or at least not all model instance fields. In this case make a request with the PATCH http method. Django rest framework (DRF) will take care of it out of the box.
Example (with token auth):