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

Django如何返回一对多关联数据?附模型类及序列化器代码

在Django REST Framework中返回一对多关联数据的方案

针对你定义的plans(主表)和plan_cat(从表,外键关联plans)的一对多关系,下面几种实用方法可以帮你在序列化时返回关联的所有plan_cat数据:

方法1:嵌套序列化器(最常用、最灵活)

先定义plan_cat的序列化器,再在plans的序列化器中嵌套它,就能把每个套餐对应的所有分类一起返回:

from rest_framework import serializers
from .models import plans, plan_cat

# 先定义从表的序列化器
class PlanCatSerializer(serializers.ModelSerializer):
    class Meta:
        model = plan_cat
        fields = ['id', 'cat_name', 'cat_is_active']

# 主表序列化器,嵌套关联的分类序列化器
class PlanSerializer(serializers.ModelSerializer):
    # 这里的`plan_cat_set`是Django默认的反向关联名称(模型名小写+_set)
    # 如果你的外键字段定义了related_name,就替换成你设置的名称
    plan_cats = PlanCatSerializer(source='plan_cat_set', many=True, read_only=True)

    class Meta:
        model = plans
        fields = ['id', 'plan_name', 'plan_price', 'plan_is_active', 'plan_cats']

序列化后返回的格式大概是这样:

{
  "id": 1,
  "plan_name": "基础套餐",
  "plan_price": 99,
  "plan_is_active": true,
  "plan_cats": [
    {"id": 1, "cat_name": "基础服务", "cat_is_active": true},
    {"id": 2, "cat_name": "售后支持", "cat_is_active": true}
  ]
}

方法2:用depth参数快速实现嵌套

如果只是想简单返回关联模型的所有字段,不想单独写嵌套序列化器,可以用depth参数自动递归序列化关联数据:

class PlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = plans
        fields = ['id', 'plan_name', 'plan_price', 'plan_is_active', 'plan_cat_set']
        depth = 1  # 指定序列化1层关联数据

这种方法适合快速测试或简单场景,但灵活性差,没法自定义关联字段的返回内容。

方法3:SerializerMethodField自定义返回逻辑

如果需要对关联数据做额外处理(比如只返回活跃的分类),可以用这个方法定制返回逻辑:

class PlanSerializer(serializers.ModelSerializer):
    active_plan_cats = serializers.SerializerMethodField()

    class Meta:
        model = plans
        fields = ['id', 'plan_name', 'plan_price', 'plan_is_active', 'active_plan_cats']

    def get_active_plan_cats(self, obj):
        # 过滤出仅活跃的分类并序列化
        active_cats = obj.plan_cat_set.filter(cat_is_active=True)
        return PlanCatSerializer(active_cats, many=True).data

额外性能优化提示

如果数据量较大,记得在视图中用prefetch_related避免N+1查询问题:

from rest_framework import generics
from .models import plans
from .serializers import PlanSerializer

class PlanList(generics.ListAPIView):
    queryset = plans.objects.prefetch_related('plan_cat_set').all()
    serializer_class = PlanSerializer

另外提个小建议:把模型名改成大驼峰格式(比如Plan代替plans,PlanCategory代替plan_cat),这是Python和Django的通用命名规范,代码会更易读~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:17:29