DRF中ManyToManyField的自定义序列化器和ViewSet [重复]

Posted

技术标签:

【中文标题】DRF中ManyToManyField的自定义序列化器和ViewSet [重复]【英文标题】:Custom Serializer and ViewSet for ManyToManyField in DRF [duplicate] 【发布时间】:2019-12-13 13:33:02 【问题描述】:

我在EntityEntityGroup 之间有M2M 关系,我想将相应的实体索引保存到EntityGroup,就像将实体数组保存到数据库一样。

由于我使用了一个自定义的模型,里面有额外的字段index,我需要将index序列化为对应的entity响应,我应该如何实现呢?

我是 django 和 django-rest-framework 的新手,经过几次谷歌搜索后似乎没有类似的 M2M 示例。这是我的想法,序列化程序只能序列化具有ForeignKey 关系的唯一一个模型的字段,视图集可以具有基于queryset 的自定义模型,它可以合并几个模型的关系。所以我需要实现一个更可扩展的视图集,里面有一个自定义的queryset

这是我的代码:

models.py

class Entity(models.Model):
    uuid = models.CharField()
    name = models.CharField()

class EntityGroup(models.Model):
    name = models.CharField()
    entities = models.ManyToManyField(Entity,
        through='EntityGroupRelationship',
        through_fields=('group', 'entity'),
        related_name='groups'
    )

class EntityGroupRelationship(models.Model):
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE)
    group = models.ForeignKey(EntityGroup, on_delete=models.CASCADE)
    index = models.PositiveIntegerField()

序列化器.py

class EntitySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entity
        fields = '__all__'

class EntityGroupRelationshipSerializer(serializers.ModelSerializer):
    class Meta:
        model = EntityGroupRelationship
        fields = '__all__'

class EntityGroupSerializer(serializers.ModelSerializer):
    entities = EntitySerializer(many=True)

    class Meta:
        model = EntityGroup
        fields = '__all__'

views.py

class EntityGroupViewSet(BaseModelViewSet):
    queryset = EntityGroup.objects.all()
    serializer_class = EntityGroupSerializer

class EntityGroupRelationshipViewSet(BaseModelViewSet):
    queryset = EntityGroupRelationship.objects.all()
    serializer_class = EntityGroupRelationshipSerializer

当前响应

[
    
        "id": 1,
        "entities": [
            "id": 1,
            "name": "",
        ]
    ,
    ...
]

预期响应

[
    
        "id": 1,
        "entities": [
            
                "index": 1,
                "info": 
                    "id": 1,
                    "name": "",
                
            
        ]
    ,
    ...
]

【问题讨论】:

【参考方案1】:

您为此使用了不正确的序列化程序。使用EntityGroupRelationshipSerializer 而不是EntitySerializer。另外你需要通过正确的fields

class EntitySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entity
        fields = '__all__'

class EntityGroupRelationshipSerializer(serializers.ModelSerializer):
    entity = EntitySerializer()
    class Meta:
        model = EntityGroupRelationship
        fields = ('index', 'entity')

class EntityGroupSerializer(serializers.ModelSerializer):
    entities = EntityGroupRelationshipSerializer(many=True) # here should be EntityGroupRelationshipSerializer

    class Meta:
        model = EntityGroup
        fields = '__all__'

【讨论】:

感谢萨多贝克! EntityGroupRelationshipSerializer 是我所期望的,但是EntityGroupSerializer 中的entities = EntityGroupRelationshipSerializer(many=True) 让我很困惑,Entity 没有要序列化的index 字段,(django 在我的几次尝试中报告了该错误,)那条线是错的吗? @Itachi 没有得到你的问题。你能详细说明一下吗? 算了,问题解决了,我的错。 :) @Itachi 很棒))

以上是关于DRF中ManyToManyField的自定义序列化器和ViewSet [重复]的主要内容,如果未能解决你的问题,请参考以下文章

访问 DRF ListSerializer 中的特定实例

如何在 DRF 中序列化自定义用户模型

使用自定义字段扩展 Django 的 ManyToManyField

drf--ModelSerializers序列化

DRF:Djoser 覆盖自定义用户序列化程序

Django DRF视图过滤ManyToMany查询集