我尝试使用PATCH
为我的Product API实施ModelViewSet
处理。 (产品实例主键为uuid
,因此uuid
在下面的代码中显示为lookup_field
。
我对如何覆盖update()
ModelSerializer类方法感到困惑。源中的存根看起来像这样:
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)
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
答案 0 :(得分:3)
这是一个很好的反问题。
关键是如果没有提供instance
和validated_data
,我们会对如何访问它们提出大量疑问,加上与create
vs {{1}的混淆(他们会有相同的签名,为什么不只做一个)。
但是,您不直接调用序列化程序的update
或create
!!
您只需致电update
,它就会执行路由到serializer.save()
或create
即替换:
update
带
serializer.update() #NOT WORKING; NEEDS ARGS instance, validated_data