Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 在保存到数据库之前检查更改_Django_Python 3.x_Django Rest Framework - Fatal编程技术网

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

Django 在保存到数据库之前检查更改,django,python-3.x,django-rest-framework,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()

我正在使用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()
但是,对于上面的代码,update函数上的serializer.save()永远不会调用perform_update函数

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


我的问题围绕着为什么会发生这种情况以及我应该如何做才能实现所需的行为。

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

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)

在此原始版本中,只要在
update
方法中调用
perform\u update
。如果覆盖该方法,但仍要调用
perform\u update
,则需要将其放在那里。

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

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)

在此原始版本中,只要在
update
方法中调用
perform\u update
。如果您重写了该方法,但仍要调用
执行更新
,则需要将其放在那里。

完美!很抱歉阅读了文档,但没有阅读源代码。完全是我的错!我怀疑我是否必须在我的更新功能中手动调用perform_update。。。现在我明白了!谢谢你@dukebody!完美的很抱歉阅读了文档,但没有阅读源代码。完全是我的错!我怀疑我是否必须在我的更新功能中手动调用perform_update。。。现在我明白了!谢谢你@dukebody!