【问题标题】:Django doesn't recognize my custom update method in a serializerDjango 在序列化程序中无法识别我的自定义更新方法
【发布时间】:2020-12-09 01:12:16
【问题描述】:

我正在尝试在 Django Rest Framework 的应用程序中修补对象

但我收到以下错误

/requirements/material/12/ 处的断言错误 .update() 方法默认不支持可写嵌套字段。 为序列化器requirement.serializers.MaterialRequirementDetailSerializer 写一个显式的.update() 方法,或者在嵌套的序列化器字段上设置read_only=True

这里的主要问题是我已经创建了一个明确的更新方法。

这是我提出补丁请求的 View.py

def patch(self, request, pk, format=None): 
        requirement = models.MaterialRequirement.objects.get(pk=pk)

        serializer = serializers.MaterialRequirementDetailSerializer(
            requirement,
            data = request.data,
            partial = True
        )
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是我正在使用的序列化程序

class MaterialRequirementDetailSerializer(serializers.ModelSerializer):
    
    
    owner = UserListSerializer()
    construction_site = ConstructionSiteListSerializer()
    quotations = QuotationListSerializer(
        source='quotation_set',
        many=True,
        read_only=True
    )
    items = RequirementItemSerializer(
        many=True

    )
    state = serializers.CharField(source='get_state_display')
    type = serializers.CharField(source='get_type_display')
    delivery_time = serializers.CharField(source= 'get_delivery_time_display')

    class Meta:
        model = MaterialRequirement
        fields = (
            'id',
            'code',
            'state',
            'type',
            'deadline',
            'description',
            'observation',
            'owner',
            'construction_site',
            'delivery_date',
            'delivery_time',
            'quotations',
            'items'
        )
    
    def update(self, instance, validated_data):
        requirement = super().update(instance, validated_data)
        items = self.context.get('items', None)
        if items:
            for item in items:
                if 'id' in item.keys():
                    requirement_item = RequirementItem.objects.get(pk=item['id'])
                    if requirement_item:
                        requirement_item.name = item['name']
                        requirement_item.description = item['description']
                        requirement_item.is_urgent = item['is_urgent']
                        requirement_item.quantity = item['quantity']
                        requirement_item.save()
                else:
                    RequirementItem.objects.create(requirement = requirement, **item)
        requirement.save()
        return requirement
 

【问题讨论】:

  • 调用 super() 方法解决问题,-> super().update(instance, validated_data)
  • 你看过drf-writable-nested吗?
  • 确实是super() 方法导致了这个问题,但我不明白为什么,@ArakkalAbu
  • update(...) 方法需要 X 格式的数据,而您传递 Y 格式的数据。重写update() 方法的想法是,要么将Y 转换为X 并调用super() 方法,要么“以某种方式执行更新操作” "X.

标签: python django django-rest-framework


【解决方案1】:

这里的问题是您将super().update 与嵌套的字段一起使用。您应该将它们从验证数据中取出。并在super().update 之后使用设置它们。

def update(self, instance, validated_data):
    field = validated_data.pop("field")
    requirement = super().update(instance, validated_data)
    ...
    requirement.save()
    return requirement

【讨论】:

    猜你喜欢
    • 2014-05-18
    • 2020-04-16
    • 2016-02-17
    • 1970-01-01
    • 2021-07-02
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多