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

DRF嵌套序列化器未序列化关联数据问题求助

问题:关联模型序列化仅返回ID,自定义序列化器未生效

问题背景

尝试为API视图序列化关联模型,模型定义如下:

class Dashboard(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(IamUser, on_delete=models.CASCADE, related_name='dashboards')
    title = models.CharField(max_length=100)
    type = models.CharField(max_length=100)
    position = models.IntegerField()
    config = models.CharField(max_length=5000, blank=True, null=True)

class WidgetLayout(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(IamUser, on_delete=models.CASCADE, related_name='widgets')
    dashboard = models.ForeignKey(Dashboard, on_delete=models.CASCADE, related_name='widgets')
    type = models.ForeignKey(Widget, on_delete=models.CASCADE)
    position = models.IntegerField()
    width = models.IntegerField()
    config = models.CharField(max_length=5000, blank=True, null=True)

使用的序列化器代码:

class WidgetLayoutSerializer(serializers.ModelSerializer):
    class Meta:
        model = WidgetLayout
        fields = ['id', 'type', 'position', 'width', 'config']


class DashboardSerializer(serializers.ModelSerializer):
    class Meta:
        widgets = WidgetLayoutSerializer(many=True)
        model = Dashboard
        fields = ['id', 'title', 'position', 'config', 'type', 'widgets']

视图调用代码:

dashboards = request.user.dashboards.all()
serializer = DashboardSerializer(dashboards, many=True)

预期每个Dashboard返回对应的Widget完整JSON序列化列表,但实际仅返回Widget ID,移除widgets = WidgetLayoutSerializer(many=True)后结果一致,添加prefetch_related无效果,希望明确指定序列化器解决问题,不想使用depth=1。

问题原因

DashboardSerializer中错误地将关联字段widgets的序列化器定义放在了Meta类内部,DRF不会识别Meta类里的关联字段配置,只会默认返回关联模型的ID。

解决方案

将widgets字段的序列化器定义移到DashboardSerializer类的顶层(Meta类外部),让DRF明确使用指定的序列化器处理关联数据:

修正后的序列化器代码

class WidgetLayoutSerializer(serializers.ModelSerializer):
    class Meta:
        model = WidgetLayout
        fields = ['id', 'type', 'position', 'width', 'config']


class DashboardSerializer(serializers.ModelSerializer):
    # 关联字段定义移至类顶层
    widgets = WidgetLayoutSerializer(many=True)
    
    class Meta:
        model = Dashboard
        fields = ['id', 'title', 'position', 'config', 'type', 'widgets']

优化查询性能(可选)

修正序列化器后,配合prefetch_related预加载关联数据,避免N+1查询问题:

dashboards = request.user.dashboards.prefetch_related('widgets').all()
serializer = DashboardSerializer(dashboards, many=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:40:26