Django REST Framework在PUT上更新外键字段

时间:2018-09-30 16:41:50

标签: django django-rest-framework

我正在使用Django 2.xDjango 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 ModeOfPaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModeOfPayment
        fields = ('id', 'title')


class AmountGivenSerializer(serializers.ModelSerializer):
    mode_of_payment = ModeOfPaymentSerializer()

    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

views.py

class AmountGivenViewSet(viewsets.ModelViewSet):
    serializer_class = AmountGivenSerializer
    permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
    filter_fields = ('contact__id',)

    def get_queryset(self):
        queryset = AmountGiven.objects.filter(
            contact__user=self.request.user
        )

        return queryset

但是当我使用带有{strong> PUT 方法的postman发布数据来更新现有记录

enter image description here

它仍然说

{
    "mode_of_payment": [
        "This field is required."
    ]
}
  

编辑2:丹尼尔回答后的回应

{
    "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",
}

1 个答案:

答案 0 :(得分:1)

您已通过将mode_of_payment字段设置为ModeOfPaymentSerializer来告诉AmountSerializer接受表示ModeOfPayment实例的嵌套字典。但这不是您要发送的内容。您正在发送ModeOfPayment的ID。

您应该在AmountGivenSerializer中删除该行。

修改

我错了,您需要将该字段显式声明为PrimaryKeyRelatedField:

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

    class Meta:
        ...

现在它将接受数据中的UUID。