首页 > 解决方案 > Django REST Framework 序列化程序 PrimaryKeyRelatedField() 不在 GET 响应中添加对象

问题描述

我正在使用Django 2.x和`Django REST Framework。

我有models.py,内容为

class ModeOfPayment(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField()

class AmountGiven(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
    amount = models.FloatField()
    mode_of_payment = models.ForeignKey(
        ModeOfPayment,
        on_delete=models.PROTECT,
        blank=True,
        default=None,
        null=True
    )

serializers.py

class AmountGivenSerializer(serializers.ModelSerializer):
    mode_of_payment = serializers.PrimaryKeyRelatedField(queryset=ModeOfPayment.objects.all())

    class Meta:
        model = AmountGiven
        depth = 1
        fields = (
            'id', 'contact', 'amount', 'mode_of_payment', 
        )

    def update(self, instance, validated_data):
        mode_of_payment = validated_data.pop('mode_of_payment')
        instance.mode_of_payment_id = mode_of_payment.id
        return instance

这很好用,因为我可以更新mode_of_payment字段。但是在调用时响应amount_given不包含mode_of_payment对象的参数。

反应就像

{
    "id": "326218dc-66ab-4c01-95dc-ce85f226012d",
    "contact": {
        "id": "b1b87766-86c5-4029-aa7f-887f436d6a6e",
        "first_name": "Prince",
        "last_name": "Raj",
        "user": 3
    },
    "amount": 3000,
    "mode_of_payment": "0cd51796-a423-4b75-a0b5-80c03f7b1e65",
}

在删除线的同时

mode_of_payment = serializers.PrimaryKeyRelatedField(queryset=ModeOfPayment.objects.all())

确实添加了mode_of_payment带有响应的参数,但这一次不会更新mode_of_payment.amount_given

为什么mode_of_payment即使depth设置为 1 也不包含数据。

标签: djangodjango-rest-framework

解决方案


您可以ModeOfPaymentSerializer在 AmountGivenSerializer 的to_representation()方法中创建和使用它:

class ModeOfPaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModeOfPayment
        fields = (
            'id', 'title',
        )

class AmountGivenSerializer(serializers.ModelSerializer):
    mode_of_payment = serializers.PrimaryKeyRelatedField(queryset=ModeOfPayment.objects.all())

    class Meta:
        model = AmountGiven
        fields = (
            'id', 'contact', 'amount', 'mode_of_payment', 
        )

    def update(self, instance, validated_data):
        mode_of_payment = validated_data.pop('mode_of_payment')
        instance.mode_of_payment_id = mode_of_payment.id
        return instance

    def to_representation(self, value):
        data = super().to_representation(value)  
        mode_serializer = ModeOfPaymentSerializer(value.mode_of_payment)
        data['mode_of_payment'] = mode_serializer.data
        return data

推荐阅读