Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In the Django REST framework, how to allow partial updates when using a ModeViewSet?

I'd like to create a REST API for an object which can be partially updated. On http://www.django-rest-framework.org/api-guide/serializers/#partial-updates and example is given in which partial=True is passed when instantiating the serializer:

# Update `comment` with partial data
serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)

In my case, however, the model (which is called SessionType) has the following viewset:

class SessionTypeViewSet(viewsets.ModelViewSet):
    queryset = SessionType.objects.all()
    serializer_class = SessionTypeSerializer

where the serializer is defined as

class SessionTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = SessionType
        fields = ('title',)

How can I adapt the serializer in this use case so that partial is always True?

like image 249
Kurt Peek Avatar asked Jan 25 '18 19:01

Kurt Peek


2 Answers

You don't need to adapt the serializer in any way. With that viewset, any call to the "detail" endpoint using the PATCH method will do a partial update.

The Django Rest Framework ModelViewSet base class includes the following mixin. Here you can see how partial=True is passed when calling partial_update, which is routed to the PATCH method by default:

class UpdateModelMixin(object):
    """
    Update a model instance.
    """
    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)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # refresh the instance from the database.
            instance = self.get_object()
            serializer = self.get_serializer(instance)

        return Response(serializer.data)

    def perform_update(self, serializer):
        serializer.save()

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)
like image 155
dukebody Avatar answered Oct 13 '22 20:10

dukebody


The partial update is implicit in the ModelViewset acoording with the documentation the only thing you need to do is call the "SessionTypeViewSet" endpoint with the method PATCH

like image 33
Ligorio Edwin Salgado Flores Avatar answered Oct 13 '22 21:10

Ligorio Edwin Salgado Flores