保存到数据库之前检查更改

时间:2018-01-25 16:03:29

标签: django python-3.x django-rest-framework

我正在使用Django 1.11和DRF 3.6.2,刚刚开始开发API ......

我正在尝试检查数据库中要发送的数据有哪些更改。

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()

但是,使用上面的代码,更新函数上的serializer.save()永远不会调用perform_update函数。

根据文档,ModelViewSet继承自GenericAPIView并且它具有UpdateModelMixin,它应该在保存之前自动调用perform_update函数

我的问题围绕着它为什么会发生以及我该如何做才能达到理想的行为。

1 个答案:

答案 0 :(得分:1)

这是因为您要覆盖自定义视图集中的update方法。这是UpdateModelMixin混入的ModelViewSet的原始代码:

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)

在此原始版本中,只要perform_update方法,就会调用update。如果您覆盖该方法但仍想调用perform_update,则需要将其放在那里。