meetnick
meetnick

Reputation: 1196

check changes before saving into database

I am using Django 1.11 and DRF 3.6.2 and just started developing an API...

I am trying to check what are the changes to be performed in the database with the data being sent.

class IndividualViewSet(viewsets.ModelViewSet):
    """Individual ViewSet."""

    serializer_class = serializers.IndividualSerializer
    queryset = models.Individual.objects.all()

    def update(self, request, equipment_serial, pk=None):
        queryset = models.Individual.objects.get(pk=pk)
        serializer = serializers.IndividualSerializer(queryset, data=request.data["entities"][0])
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status.HTTP_200_OK)
        return Response(status.HTTP_400_BAD_REQUEST)

    def perform_update(self, serializer):
        old_obj = self.get_object()
        new_data_dict = serializer.validated_data

        if old_obj.name != new_data_dict['name']:
            # logic for different data
            # ...
        serializer.save()

However, with the code as above, the perform_update function is never being called by serializer.save() on the update function.

According to the docs, ModelViewSet is inherited from GenericAPIView and it has UpdateModelMixin, which should automatically calls the perform_update function before saving

My questions surrounds on why it is happen and how should I do in order to accomplish the desired behaviour.

Upvotes: 0

Views: 557

Answers (1)

dukebody
dukebody

Reputation: 7185

This is because you are overriding the update method in your custom viewset. This is the original code for the UpdateModelMixin that the ModelViewSet mixes in:

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)

In this original version, perform_update is called whenever in the update method. If you override that method and still want to call perform_update, you need to put it there.

Upvotes: 2

Related Questions