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": [] }, ... ]
问题原因
flatten_list函数无效:category_list本身就是扁平的分类对象列表,不存在嵌套的子列表,函数里的isinstance(item, list)判断永远不成立,函数只是原样返回了列表。- 序列化器保留嵌套字段:核心问题是
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
相关产品推荐
相关产品推荐

