繁体   English   中英

使用to_internal_value()和to_representation()的Django Rest Framework读写平面序列化器

[英]Django Rest Framework read-write flat serializer using to_internal_value() and to_representation()

我已经在drf文档之后成功实现了writable-nested-serializer,并且还可以使用to_representation()方法更改其表示形式以使其看起来更整洁。

\\ initial数据结构,其中POST与修改的crete()一起正常工作

{
    "id": 1033,
    "client": {
        "client_name": "BAC"
    },
    "brand": {
        "brand_name": "SDA"
    },
    "order_date": "2018-01-25",
    "shipment_date": "2018-01-26"
}

在应用to_representation()和PATCH之后的\\ data结构可以使用经过修改的update()很好,但不能进行POST,而PUT则不能。

    {
        "id": 1033,
        "order_date": "2018-01-25",
        "shipment_date": "2018-01-26",
        "client_name": "BAC",
        "brand_name": "SDA"
    }

但是,我似乎无法正确实现to_internal_value()方法,因此我可以使用新的表示形式编写可写嵌套的序列化器。 以下是尽管自定义create()方法和使用所需数据进行POST所收到的错误。

\\发布数据

{
    "order_date": "2017-10-26",
    "shipment_date": "2017-11-11",
    "client_name": "ABC",
    "brand_name": "DEF"
}

\\错误信息

{
    "client": [
        "This field is required."
    ],
    "brand": [
        "This field is required."
    ]
}

下面是我的代码。 使用PATCH时,update()方法可以正常工作。 但是POST和PUT无法正常工作,因此我认为我缺少一些正确链接create()和to_internal_value()方法的代码。 任何帮助将非常感激。

/serializers.py

class OrderSerializer(serializers.ModelSerializer):
    client = ClientSerializer()
    brand = BrandSerializer()

    class Meta:
        model = Order
        fields = ('id', 'client', 'brand', 'order_date',
                  'shipment_date',)

    def to_representation(self, obj):
        representation = super().to_representation(obj)
        client_representation = representation.pop('client')
        brand_representation = representation.pop('brand')
        for key in client_representation:
            representation[key] = client_representation[key]
        for key in brand_representation:
            representation[key] = brand_representation[key]
        return representation

    def to_internal_value(self, data):
        client_internal = {}
        brand_internal = {}
        for key in ClientSerializer.Meta.fields:
            if key in data:
                client_internal[key] = data.pop(key)
        for key in BrandSerializer.Meta.fields:
            if key in data:
                brand_internal[key] = data.pop(key)
        internal = super(OrderSerializer, self).to_internal_value(data)
        internal['client'] = client_internal
        internal['brand'] = brand_internal

        return internal

    def create(self, validated_data):
        client_data = validated_data.pop('client')
        brand_data = validated_data.pop('brand')
        client, created = Client.objects.get_or_create(
            client_name=client_data['client_name'])
        brand, created = Brand.objects.get_or_create(
            brand_name=brand_data['brand_name'])
        order = Order.objects.create(
            client=client, brand=brand, **validated_data)
        return order

    def update(self, instance, validated_data):
        client_data = validated_data.pop('client')
        brand_data = validated_data.pop('brand')
        client, created = Client.objects.get_or_create(
            client_name=client_data['client_name'])
        brand, created = Brand.objects.get_or_create(
            brand_name=brand_data['brand_name'])
        instance.brand = brand
        instance.client = client
        instance.order_date = validated_data['order_date']
        instance.shipment_date = validated_data['shipment_date']
        instance.save()
        return instance

我尝试了您的代码,并且正如我在评论中建议的那样,这应该对您有所帮助:

class OrderSerializer(serializers.ModelSerializer):
    client = ClientSerializer(required=False)
    brand = BrandSerializer(required=False)

有了这个,我能够用您的json输入发送POST请求,并创建订单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM