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

如何将层级字典列表转换为HTML多级下拉菜单?

多级HTML下拉菜单生成问题

现有一个层级可扩展的字典列表WIDGETS,需要将其转换为符合Bootstrap样式的多级下拉菜单HTML结构。尝试了递归函数但未正常工作,以下是问题详情及修正方案:

原始数据

WIDGETS = [
    {"id": 1, "pid": 0, "url": "/upload"},
    {"id": 2, "pid": 0, "url": "/entry"},
    {"id": 3, "pid": 0, "url": "/report"},
    {"id": 4, "pid": 3, "url": "/reppremium"},
    {"id": 5, "pid": 4, "url": "/reppremiumsum"},
    {"id": 6, "pid": 4, "url": "/reppremiumfull"},
    {"id": 7, "pid": 3, "url": "/repcommission"},
    {"id": 8, "pid": 7, "url": "/repcommissionsum"},
    {"id": 9, "pid": 7, "url": "/repcommissionfull"},
    {"id": 10, "pid": 3, "url": "/repportions"},
    {"id": 11, "pid": 10, "url": "/repportionssum"},
    {"id": 12, "pid": 10, "url": "/repportionsfull"},
    {"id": 13, "pid": 0, "url": "/adduser"},
    {"id": 14, "pid": 0, "url": "/exportdb"},
    {"id": 15, "pid": 0, "url": "/importdb"},
]

期望的菜单结构

main menu -> /upload
             /report -> /reppremium    ->  /reppremiumsum
                                       ->   /reppremiumfull

                     -> /repcommission ->  /repcommissionsum
                                       ->  /repcommissionfull


                     -> /repportions   ->  /repportionssum
                                       ->  /repportionsfull
             /adduser
             /exportdb
             /importdb

原错误代码

def get_widgets(widgets,text='',pid=0,text_m=''):
    childs = get_childs(pid,widgets)
    for child in childs:
 
        pidn = child['id']
        n = get_childs(pidn,widgets)
        print(n,'for id',pidn)


        if len(n) != 0:
            text += f'''
            <li class="nav-item dropend">
            <a class="nav-link dropdown-toggle" href="{ child['url'] }" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                { child['url'] }
            </a>
            <ul class="dropdown-menu nav nav-pills flex-column mb-sm-auto mb-0 align-items-center align-items-sm-start">
            '''
            pid_new = child['id']
            get_widgets(widgets,text,pid_new)
            text += '</ul></li>'
            print(text)
            text_m += text
        else:
            #print(n,'n')
            text += f'''
            <li class="nav-item">
                <a class="nav-link dropdown-item" href="{ child['url'] }">{ child['url'] }</a>
            </li>
            ''' 
            text_m += text
    


        text = ''



 
    return tex

问题分析

  1. 递归调用未接收返回的HTML片段,导致子菜单内容丢失
  2. text和text_m变量管理混乱,循环内重置text会丢失部分内容
  3. 函数返回值拼写错误(tex应为text_m)
  4. 缺少get_childs实现,且每次递归遍历全量数据效率低下

修正方案

步骤1:预分组子节点优化结构

先按pid分组所有节点,避免重复遍历:

from collections import defaultdict

def build_widget_tree(widgets):
    tree = defaultdict(list)
    for widget in widgets:
        tree[widget['pid']].append(widget)
    return tree

步骤2:重写递归生成函数

修正变量逻辑,正确拼接子菜单内容:

def generate_menu_html(widget_tree, pid=0):
    html_fragments = []
    for widget in widget_tree[pid]:
        children = widget_tree[widget['id']]
        if children:
            # 生成带下拉的父节点
            html_fragments.append(f'''
            <li class="nav-item dropend">
                <a class="nav-link dropdown-toggle" href="{widget['url']}" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                    {widget['url']}
                </a>
                <ul class="dropdown-menu">
                    {generate_menu_html(widget_tree, widget['id'])}
                </ul>
            </li>
            ''')
        else:
            # 生成普通菜单项
            html_fragments.append(f'''
            <li class="nav-item">
                <a class="nav-link dropdown-item" href="{widget['url']}">{widget['url']}</a>
            </li>
            ''')
    return '\n'.join(html_fragments).strip()

步骤3:完整调用示例

# 构建树结构
widget_tree = build_widget_tree(WIDGETS)
# 生成完整主菜单HTML
main_menu_html = f'''
<ul class="nav nav-pills flex-column mb-sm-auto mb-0 align-items-center align-items-sm-start">
    {generate_menu_html(widget_tree)}
</ul>
'''

# 输出或使用生成的HTML
print(main_menu_html)

说明

  • 生成的HTML适配Bootstrap 5下拉菜单样式,需确保页面已引入Bootstrap的CSS和JS资源
  • 预分组的树结构大幅提升递归效率,尤其适用于大数据量场景
  • 用列表拼接HTML片段,避免字符串拼接的性能损耗,逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:30:36