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

Django如何循环渲染无限层级的嵌套列表?

解决无限层级嵌套列表的修改方案

一、修改查询逻辑(视图层)

核心是建立父项与子项的映射关系,而非分开传递顶级和所有子项:

  1. 先查询所有Item数据,按「父项ID」分组构建字典(如child_map),键为父项ID,值为对应直接子项列表。假设你的Hierarchy模型通过parent和child外键关联Item,代码示例:

    from django.shortcuts import render
    from .models import Item
    
    def item_list(request):
        all_items = Item.objects.all()
        child_map = {}
        for item in all_items:
            # 根据你的模型关联逻辑获取父项ID,这里假设Item有parent_id字段
            parent_id = item.parent_id if hasattr(item, 'parent_id') else item.hierarchy.parent.id
            if parent_id not in child_map:
                child_map[parent_id] = []
            child_map[parent_id].append(item)
        top_level_items = Item.objects.filter(toplevel=True)
        return render(request, 'item_list.html', {
            'top_level_items': top_level_items,
            'child_map': child_map
        })
    
  2. 若使用Django 3.2+,也可通过Prefetch预加载子项,但字典映射方式更直观,适配任意深度层级。

二、修改模板循环(模板层)

采用递归渲染逻辑,让每个项渲染完成后,自动调用相同逻辑渲染其子项:

  1. 创建可复用的递归模板片段(如_item_recursive.html):

    {% for item in items %}
        <li>
            {{ item.name }}
            <!-- 检查当前项是否存在子项 -->
            {% if child_map.get(item.id) %}
                <ul>
                    <!-- 递归调用模板片段,传入当前项的子列表 -->
                    {% include "_item_recursive.html" with items=child_map.get(item.id) %}
                </ul>
            {% endif %}
        </li>
    {% endfor %}
    
  2. 在主模板(item_list.html)中引入该片段,传入顶级Item:

    <ul>
        {% include "_item_recursive.html" with items=top_level_items %}
    </ul>
    

三、额外优化(可选)

若层级极深或数据量大,可使用数据库递归查询(如PostgreSQL的WITH RECURSIVE)一次性获取完整层级结构,减少模板层遍历开销:

from django.db import connection

def get_hierarchy_items():
    with connection.cursor() as cursor:
        cursor.execute("""
            WITH RECURSIVE item_hierarchy AS (
                SELECT id, name, parent_id, 1 as level
                FROM yourapp_item
                WHERE toplevel = TRUE
                UNION ALL
                SELECT i.id, i.name, i.parent_id, ih.level + 1
                FROM yourapp_item i
                JOIN item_hierarchy ih ON i.parent_id = ih.id
            )
            SELECT * FROM item_hierarchy ORDER BY level, id;
        """)
        columns = [col[0] for col in cursor.description]
        return [dict(zip(columns, row)) for row in cursor.fetchall()]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:01:16