我正在使用 Django 2.2 和 Django REST Framework 。
我有一个端点来更新现有记录,扩展了 UpdateAPIView
class FakeOrderPaymentView(generics.UpdateAPIView):
serializer_class = OrderPaymentSerializer
permission_classes = (IsAuthenticated,)
def get_object(self):
log.debug(self.request.data)
order_id = self.request.data.get('order_id', None)
if not order_id:
raise Http404
return self.serializer_class.Meta.model.objects.filter(pk=order_id).first()
def perform_update(self, serializer):
return serializer.save()
def update(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = self.perform_update(serializer)
instance_serializer = OrderListSerializer(instance)
return Response(instance_serializer.data)
和 OrderPaymentSerializer
class OrderPaymentSerializer(serializers.ModelSerializer):
order_id = serializers.IntegerField(write_only=True, required=False)
order_status = serializers.CharField(write_only=True, required=True)
class Meta:
model = Order
fields = [
'order_status',
'order_id'
]
def create(self, validated_data):
log.debug(validated_data)
return super().create(validated_data)
def update(self, instance, validated_data):
status = validated_data.pop('order_status', None)
order_id = validated_data.pop('order_id', None)
instance.status = Order.STATUS.COMPLETED
return super().update(instance, validated_data)
order_id 和 order_status 不是模型字段。他们只是为了携带数据。
如果order_id
不在PUT数据中,或者order_id
为空白。它应该会引发404响应。
但是,它不是在get_object()
之前调用update()
方法。
同样,即使我在PUT数据中传递了order_id
。 perform_update()
方法正在调用序列化程序的create()
方法,而不是update()
方法。
update()
方法?get_object()
没有自动呼叫?答案 0 :(得分:0)
- 何时调用序列化程序的update()方法?
调用.save()将创建一个新实例,或更新一个现有实例,具体取决于在实例化序列化程序类时是否传递了一个现有实例
由于在实例化序列化程序时未提供实例,因此调用save
将转换为create
而不是update
。
- 为什么get_object()没有自动调用?
因为您查看的update
方法已被覆盖,而您没有调用get_object
。默认DRF update
为:
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
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data)