在django rest框架中对ModelViewSet的PATCH请求 - 如何实现serializer.update()?

时间:2017-06-23 09:34:45

标签: python django django-rest-framework

我尝试使用PATCH为我的Product API实施ModelViewSet处理。 (产品实例主键为uuid,因此uuid在下面的代码中显示为lookup_field

我对如何覆盖update() ModelSerializer类方法感到困惑。源中的存根看起来像这样:

def update(self, instance, validated_data):
    raise NotImplementedError('`update()` must be implemented.')

我不明白为什么应该提供instancevalidated_data,因为它们应该是序列化程序的属性,因为它的实例化: get_serializer(self, instance=None, data=None, many=False, partial=False)(向上滚动一段here in the documentation)。为什么我要提供经过验证的数据?串行器应该验证它吗?

这是我的partial_update()实施:

product.py(ViewSet类)

def get_object(self, uuid=None):
    """ Utility method to get the object """
    # authentication logic, returns None if object not found

def partial_update(self, request, uuid=None):
    instance = self.get_object(uuid)
    if not instance:
        return Response(status=status.HTTP_404_NOT_FOUND)
    serializer = self.get_serializer(instance, 
                    data=request.data,
                    many=isinstance(request.data, list),
                    partial=True)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data
    return Response(serializer.data, status=status.HTTP_200_OK)

serializers.py

def update(self, instance, validated_data):
    # we link up the user foreign key here
    user=User.objects.filter(email=validated_data.pop('user', None)).first()
    if user:
        instance.fk_user = user

    #specify which fields to update, otherwise save() tries to SQL SET all fields
    update_fields = [k for k in validated_data]
    if user:
        update_fields.append('fk_user')
    for k,v in validated_data.items():
        setattr(instance, k, v)
    instance.save(update_fields=update_fields)
    return instance

1 个答案:

答案 0 :(得分:3)

这是一个很好的反问题。

关键是如果没有提供instancevalidated_data,我们会对如何访问它们提出大量疑问,加上与create vs {{1}的混淆(他们会有相同的签名,为什么不只做一个)。

但是,您直接调用序列化程序的updatecreate !!

您只需致电update,它就会执行路由到serializer.save()create

即替换:

update

serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data