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

Django中嵌套分类列表转扁平列表失败求助

问题:分类列表无法输出为扁平结构,仍显示嵌套格式

我希望将分类列表输出为扁平列表,但现有代码未实现该功能,输出结果中每个分类对象仍带有children嵌套结构。

我的实现代码

@api_view(['GET'])
def AllCategoriesList(request):
    categories = Categories.objects.filter(parent=None).prefetch_related(
        Prefetch('children', queryset=Categories.objects.all(), to_attr='subcategories')
    )
    
    def flatten_list(lst):
        flat_lst = []
        for item in lst:
            if isinstance(item, list):
                flat_lst.extend(flatten_list(item))
            else:
                flat_lst.append(item)
        
        return flat_lst
    
    category_list = []
    for category in categories:
        category_list.append(category)
        category_list.extend(category.children.all())

    flattened_list = flatten_list(category_list)

    serializer = CategorieSerializer(flattened_list, many=True)
    return Response(serializer.data)

当前输出示例(简化)

[
  {
    "id": 1,
    "nom_categorie": "Test categorie",
    "children": [{"id": 2, "nom_categorie": "nouveau categorie", ...}]
  },
  {
    "id": 2,
    "nom_categorie": "nouveau categorie",
    "children": []
  },
  ...
]

问题原因

  1. flatten_list函数无效:category_list本身就是扁平的分类对象列表,不存在嵌套的子列表,函数里的isinstance(item, list)判断永远不成立,函数只是原样返回了列表。
  2. 序列化器保留嵌套字段:核心问题是CategorieSerializer默认会序列化children字段,导致每个分类对象都会带上自己的子分类数据,即使已经把所有子分类单独放到了列表中。

解决方案

方案1:修改序列化器,排除children字段

直接在序列化时去掉children字段,让每个分类对象只返回自身数据,不包含子分类嵌套:

# 调整你的序列化器
class CategorieSerializer(serializers.ModelSerializer):
    class Meta:
        model = Categories
        # 明确列出需要返回的字段,不包含children
        fields = ['id', 'image_couverture', 'nom_categorie', 'descriptions', 'slug', 'created_at', 'updated_at', 'parent']
        # 或者用exclude快速排除children字段
        # exclude = ['children']

方案2:直接查询所有分类,简化代码

不需要先查父类再拼接子类,直接查询所有分类对象即可,代码更简洁高效:

@api_view(['GET'])
def AllCategoriesList(request):
    # 直接获取所有分类,自动返回扁平列表
    categories = Categories.objects.all()
    # 使用修改后的序列化器(排除children字段)
    serializer = CategorieSerializer(categories, many=True)
    return Response(serializer.data)

方案3:保留父类关联但不嵌套(可选)

如果需要显示父类名称等关联信息,但不需要嵌套子分类,可以在序列化器中添加父类相关字段:

class CategorieSerializer(serializers.ModelSerializer):
    # 添加父类名称字段(可选)
    parent_name = serializers.CharField(source='parent.nom_categorie', allow_null=True)
    
    class Meta:
        model = Categories
        fields = ['id', 'image_couverture', 'nom_categorie', 'descriptions', 'slug', 'created_at', 'updated_at', 'parent', 'parent_name']
        exclude = ['children']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:47:03