You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DRF中序列化多对多字段?反向关联查询失败求助

问题:从literature_info反向获取关联dataset_info的序列化失败

模型定义

models.py中的三个模型类:

class literature_info(models.Model):
    pmid = models.CharField(primary_key=True,max_length=25)
    publication = models.CharField(max_length=50, blank=True, null=True)
    def __str__(self):
        return self.pmid
    
class dataset_info(models.Model):
    dataset_id = models.CharField(primary_key=True,max_length=25)
    literature = models.ManyToManyField(literature_info, through='literature_dataset', blank=True)
    def __str__(self):
        return self.dataset_id

class literature_dataset(models.Model):
    literature_info = models.ForeignKey(literature_info, on_delete=models.CASCADE)
    dataset_info = models.ForeignKey(dataset_info, on_delete=models.CASCADE)

正向序列化(正常工作)

从dataset_info获取关联文献的序列化器:

class literature_info_serializer(serializers.ModelSerializer):
    class Meta:
        model = literature_info
        fields = "__all__"

class dataset_literature_serializer(serializers.ModelSerializer):
    literature = literature_info_serializer(many=True)
    class Meta:
        model = dataset_info
        fields = ('dataset_id','literature',)

反向序列化问题

尝试从literature_info反向获取关联数据集的序列化器无法正常工作:

class dataset_info_serializer(serializers.ModelSerializer):
    class Meta:
        model = dataset_info
        fields = ('dataset_id',)


class literature_dataset_serializer(serializers.ModelSerializer):
    dataset_info = dataset_info_serializer(many=True)
    class Meta:
        model = literature_info
        fields = ('pmid', 'dataset_info',)

解决方法

问题出在反向关联的字段名称上:在dataset_info的literature多对多字段中,没有显式指定related_name,Django默认的反向关联名称是dataset_info_set(模型名小写+_set),而非你写的dataset_info。

方法一:使用默认反向关联名称修改序列化器

直接把序列化器中的字段名改成默认的dataset_info_set:

class dataset_info_serializer(serializers.ModelSerializer):
    class Meta:
        model = dataset_info
        fields = ('dataset_id',)


class literature_dataset_serializer(serializers.ModelSerializer):
    dataset_info_set = dataset_info_serializer(many=True)
    class Meta:
        model = literature_info
        fields = ('pmid', 'dataset_info_set',)

方法二:显式设置related_name(更优雅)

先修改dataset_info模型中的多对多字段,添加related_name参数自定义反向关联名称:

class dataset_info(models.Model):
    dataset_id = models.CharField(primary_key=True,max_length=25)
    # 添加related_name指定反向关联名称
    literature = models.ManyToManyField(literature_info, through='literature_dataset', blank=True, related_name='datasets')
    def __str__(self):
        return self.dataset_id

然后修改序列化器,使用指定的datasets作为字段名:

class dataset_info_serializer(serializers.ModelSerializer):
    class Meta:
        model = dataset_info
        fields = ('dataset_id',)


class literature_dataset_serializer(serializers.ModelSerializer):
    datasets = dataset_info_serializer(many=True)
    class Meta:
        model = literature_info
        fields = ('pmid', 'datasets',)

两种方法都能解决反向序列化问题,推荐第二种,字段名更直观易懂。

内容的提问来源于stack exchange,提问作者Bioinfotec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:22:39