我正在尝试使用 ModelViewSet 为我的产品 API 实现 PATCH 处理。 (Product 实例主键是 uuid,因此 uuid 在下面的代码中显示为 lookup_field)。
我对如何覆盖 update() ModelSerializer 类方法感到困惑。源代码中的 stub 如下所示:
def update(self, instance, validated_data):
raise NotImplementedError('`update()` must be implemented.')
我不明白为什么要提供 instance 和 validated_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)
序列化器.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
请您参考如下方法:
这是一个很好且明智的问题。
重点是,如果未提供 instance 和 validated_data,我们将有大量关于如何访问它们的问题,加上一些与 create 的混淆 vs update(它们会有相同的签名,那为什么不只做一个)。
但是,您不应该直接调用序列化程序的create 或update!!
您只需调用 serializer.save(),它就会执行到 create 或 update 的路由
即替换:
serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data
与
serializer.save()
