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

Django REST Framework序列化器无法显示关联模型数据求助

我来帮你解决这个问题!你遇到的核心问题是Django ORM默认的反向关联名称和你序列化器里使用的字段名不匹配,导致DRF无法找到对应的关联数据。另外你的模型里还有一个拼写错误需要先修复,我一步步给你讲清楚:

第一步:修复模型中的拼写错误

先看你的EntityRangeData模型,外键字段名拼错了,这个错误会导致后续关联数据无法正确关联,必须先修正:

# 原错误代码
class EntityRangeData(Data):
    enityrange = models.ForeignKey(EntityRange, on_delete=models.CASCADE)

# 修正后
class EntityRangeData(Data):
    entityrange = models.ForeignKey(EntityRange, on_delete=models.CASCADE)

第二步:解决反向关联名称不匹配的问题

Django ORM对于外键的反向关联,默认名称是小写模型名_set,比如:

  • Post和Block的关联:Post的反向字段默认是block_set,但你在PostSerializer里用了blocks
  • Block和InlineStyleRange的关联:Block的反向字段默认是inlinestylerange_set,你用了inlineStyleRanges
  • Block和EntityRange的关联:Block的反向字段默认是entityrange_set,你用了entityRanges

你有两种方法解决这个问题:

方法一:修改模型外键,添加related_name(推荐,更直观)

直接在模型的外键字段上指定related_name,让它和你序列化器里的字段名一致:

# models.py
class Block(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='blocks')  # 添加反向关联名
    key = models.CharField(max_length=255)
    text = models.TextField()
    type = models.CharField(max_length=90)
    depth = models.IntegerField(default=0)

class InlineStyleRange(models.Model):
    block = models.ForeignKey(Block, on_delete=models.CASCADE, related_name='inlineStyleRanges')  # 添加反向关联名
    offset = models.IntegerField()
    length = models.IntegerField()
    style = models.CharField(max_length=90)

class EntityRange(models.Model):
    block = models.ForeignKey(Block, on_delete=models.CASCADE, related_name='entityRanges')  # 添加反向关联名
    offset = models.IntegerField()
    length = models.IntegerField()
    key = models.IntegerField()

class EntityEntry(models.Model):
    key = models.IntegerField()
    block= models.ForeignKey(Block, on_delete=models.CASCADE, related_name='entityEntries')  # 同理添加反向关联名
    type = models.CharField(max_length=90)
    mutability = models.CharField(max_length=90)

方法二:不修改模型,在序列化器里指定source

如果你不想改动模型,可以在序列化器的字段上通过source参数指定默认的反向关联名称:

# Serializers.py
class BlockSerializer(serializers.ModelSerializer):
    # 指定source为默认的反向关联名称
    inlineStyleRanges = InlineStyleRangeSerializer(many=True, required=False, source='inlinestylerange_set')
    entityRanges = EntityRangeSerializer(many=True, required=False, source='entityrange_set')
    class Meta:
        model = models.Block
        fields = "__all__"

class PostSerializer(serializers.ModelSerializer):
    # 指定source为默认的反向关联名称
    blocks = BlockSerializer(many=True, required=False, read_only=True, source='block_set')
    class Meta:
        model = models.Post
        fields = "__all__"

第三步:修正Entity相关的序列化器

你的EntityEntrySerializer和EntityRangeSerializer里的data字段也有问题,因为EntityEntryData和EntityRangeData是多对一关联到对应的实体,所以需要加上many=True,并且指定正确的source:

# Serializers.py
class EntityEntryDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.EntityEntryData
        fields = "__all__"

class EntityEntrySerializer(serializers.ModelSerializer):
    # 一个EntityEntry可以对应多个EntityEntryData,所以加many=True并指定反向关联名
    data = EntityEntryDataSerializer(many=True, required=False, source='entityentrydata_set')
    class Meta:
        model = models.EntityEntry
        fields = "__all__"

class EntityRangeDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.EntityRangeData
        fields = "__all__"

class EntityRangeSerializer(serializers.ModelSerializer):
    # 同理,加many=True和正确的source
    data = EntityRangeDataSerializer(many=True, required=False, source='entityrangedata_set')
    class Meta:
        model = models.EntityRange
        fields = "__all__"

最后验证

做完以上修改后,如果修改了模型,记得重新迁移数据库:

python manage.py makemigrations
python manage.py migrate

然后确保你的数据库里已经有Post关联的Block、Block关联的InlineStyleRange等数据,这样DRF就能正确返回嵌套的关联内容了。比如现在你的Post序列化后应该会包含blocks字段,每个block里又包含inlineStyleRanges和entityRanges等数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:48:38