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 of partial_update
method. What is the purpose of this?
What is inside of serialized variable?
What is inside of serialized
variable in partial_update
method? Is that a Demo object? What function is called behind the scenes?
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 had the same questions as yours before, but when I dig into the source code of rest_framework, I got the following findings, hope it helps:
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 the name
and author_name
fields are mandatory (not null & not blank).
class Book(models.Model): name = models.CharField('name of the book', max_length=100) author_name = models.CharField('the name of the author', max_length=50) # Create a new instance for testing Book.objects.create(name='Python in a nut shell', author_name='Alex Martelli')
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 the Book
. So for this case, client will only submit the name
field with new value to the view. The data submit from the client may look like this:
{"pk": 1, name: "PYTHON IN A NUT SHELL"}
But you may have notice that our model definition does not allow author_name
to be blank. So we have to use partial_update
instead of update
. 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
and partial_update
, and you will get more understanding what I just said.
from rest_framework.generics import GenericAPIView from rest_framework.mixins import UpdateModelMixin from rest_framework.viewsets import ModelViewSet from rest_framework import serializers class BookSerializer(serializers.ModelSerializer): class Meta: model = Book class BookUpdateView(GenericAPIView, UpdateModelMixin): ''' Book update API, need to submit both `name` and `author_name` fields At the same time, or django will prevent to do update for field missing ''' queryset = Book.objects.all() serializer_class = BookSerializer def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) class BookPartialUpdateView(GenericAPIView, UpdateModelMixin): ''' You just need to provide the field which is to be modified. ''' queryset = Book.objects.all() serializer_class = BookSerializer def put(self, request, *args, **kwargs): return self.partial_update(request, *args, **kwargs)
urls.py urlpatterns = patterns('', url(r'^book/update/(?P<pk>\d+)/$', BookUpdateView.as_view(), name='book_update'), url(r'^book/update-partial/(?P<pk>\d+)/$', BookPartialUpdateView.as_view(), name='book_partial_update'), )
Data to submit
{"pk": 1, name: "PYTHON IN A NUT SHELL"}
When you submit the above json to the /book/update/1/
, you will got the following error with HTTP_STATUS_CODE=400:
{ "author_name": [ "This field is required." ] }
But when you submit the above json to /book/update-partial/1/
, you will got HTTP_STATUS_CODE=200 with following response,
{ "id": 1, "name": "PYTHON IN A NUT SHELL", "author_name": "Alex Martelli" }
serialized
is a object wrapping the model instance as a serialisable object. and you can use this serialized to generate a plain JSON string with serialized.data
.
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 used partial_update
.
If you still have any question, feel free to ask. I just read part of the source code of the rest framework, and may have not understand very deeply for some terms, and please point it out when it is wrong...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With