首页 > 解决方案 > Django rest 框架 POST 多对多的额外字段

问题描述

我正在尝试在 Django 中创建一个模型,该模型与另一个具有额外字段的模型具有多对多关系。我正在使用其余框架来提供对这些的 CRUD 操作,并且我相信我有一个先有鸡还是先有蛋的场景......

问题是,当我去 POST new时,由于没有要指向MainObject的 id,它会在多对多部分中引发错误。MainObject但我希望它指向MainObject我正在创建的,它在 POST 时不存在。我认为这是序列化程序的问题,但不确定如何解决。我假设我的假设也可能与我如何制定 POST 数据有关。

我正在使用 Django 2.1.8

型号代码

class RelatedObject(models.Model):
    ...

class MainObject(models.Model):
    related_objects = models.ManyToManyField(RelatedObject, through='ManyRelatedObject')

class ManyRelatedObject(models.Model):
    main_object = models.ForeignKey(MainObject, on_delete=models.DO_NOTHING)
    related_object = models.ForeignKey(RelatedObject, on_delete=models.DO_NOTHING)
    other_attribute = models.BooleanField(...)

序列化程序代码

class ManyRelatedObjectSerializer(serializers.ModelSerializer):
    main_object = serializers.PrimaryKeyRelatedField(queryset=MainObject.objects.all())
    related_object = serializers.PrimaryKeyRelatedField(queryset=RelatedObject.objects.all())

    class Meta:
        model = ManyRelatedObject
        fields = '__all__'


class MainObjectSerializer(serializers.ModelSerializer):
    related_object = ManyRelatedObjectSerializer(many=True)

    class Meta:
        model = MainObject
        fields = '__all__'

POST Payload (假设存在RelatedObject一个id为1的)

{
  "related_object": [
    {
      "related_object": 1,
      "other_attribute": true
    }
  ],
  ...
}

回复

{
  "related_object": [
    {
      "main_object": [
        "This field is required."
      ]
    }
  ]
}

目标响应:

{
  "id": 1,
  "related_object": [
    {
      "main_object": 1,
      "related_object": 1,
      "other_attribute": true
    }
  ],
  ...
}

REST 端点设置

class MainObjectViewSet(viewsets.ModelViewSet):
    queryset = MainObject.objects.all()
    serializer_class = MainObjectSerializer

标签: djangodjango-modelsdjango-rest-framework

解决方案


覆盖. __init__()_MainObjectSerializer

class MainObjectSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.context['request'].method == 'GET':
            self.fields['related_object'] = ManyRelatedObjectSerializer(many=True) 


    related_object = ManyRelatedObjectSerializer(many=True)# remove this line

    class Meta:
        model = MainObject
        fields = '__all__'

这个片段的作用是ManyRelatedObjectSerializer,如果请求是 a ,序列化程序将使用序列化程序呈现响应/输出HTTP GET,否则它将呈现股票模式( PrimaryKeyRelatedField)


推荐阅读