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

Django DRF如何实现父分类下分组嵌套展示关联子分类

DRF 按父分类聚合并嵌套返回子列表实现方案

你当前的实现以子表Service为序列化主体,所以每条子服务会单独生成一条返回记录。要实现按父分类CleaningType聚合展示子服务,只需要把查询、序列化的核心切换到父模型,再嵌套聚合关联的子数据即可。

1. 修改序列化器

直接以父模型CleaningType为序列化基础,自定义字段聚合关联的子服务名列表:

from rest_framework import serializers
from .models import CleaningType


class CleaningTypeSerializer(serializers.ModelSerializer):
    # 映射父分类名称字段,匹配返回的键名
    cleaning_type = serializers.CharField(source='cleaning_type_name')
    # 自定义字段,收集当前分类下所有子服务名称
    service_name = serializers.SerializerMethodField()

    class Meta:
        model = CleaningType
        fields = ('id', 'cleaning_type', 'service_name')

    def get_service_name(self, obj):
        # 取出当前清洁类型关联的所有服务,提取服务名组成列表返回
        # 可加order_by控制服务名的返回顺序
        return list(obj.service_set.order_by('id').values_list('service_name', flat=True))

2. 修改视图集

把查询主体从Service替换为CleaningType,加上预加载优化避免N+1查询问题:

from rest_framework.viewsets import ModelViewSet
from .models import CleaningType
from .serializers import CleaningTypeSerializer


class ServiceTypeViewSet(ModelViewSet):
    serializer_class = CleaningTypeSerializer
    http_method_names = ["get"]

    def get_queryset(self):
        # prefetch_related预加载关联服务,优化查询性能
        # 如果需要排除没有关联服务的空分类,可加上.filter(service__isnull=False).distinct()
        return CleaningType.objects.prefetch_related('service_set').all()

最终返回效果

接口返回结构会和你期望的格式完全一致:

[
  {
    "id": 1,
    "cleaning_type": "Lite service",
    "service_name": ["Floors", "Bathrooms", "Kitchen"]
  },
  {
    "id": 2,
    "cleaning_type": "Moving cleaning",
    "service_name": ["Kitchen Including All Appliances And Cabinets"]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:39:19