提问人:Alirezadigi 提问时间:1/11/2023 最后编辑:S.BAlirezadigi 更新时间:1/12/2023 访问量:112
将分层字典转换为 HTML 嵌套下拉列表
Convert hierarchical dictionary to HTML nested dropdown
问:
我有一个这样的字典列表, 但是我们可能有更多的深度,因此更多的 ID 和 PID ......
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"},
]
我想将其转换为 HTML 嵌套/多级下拉列表,如下所示:
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
我希望代码显示一个 HTML 多级下拉列表......但由小部件填充......
答:
1赞
S.B
1/12/2023
#1
正如你所猜到的,这应该是递归完成的,有几种方法可以解决它。
以下是完整的代码:
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"},
]
def build_HTML(d, text=""):
for (id_, url), children_list in d.items():
text += f"<li>{url}"
if children_list:
text += "<ul>"
for dd in children_list:
text += build_HTML(dd, "")
text += "</ul>"
text += "</li>"
return text
def set_recursive(obj, d):
for (id_, url), children_list in d.items():
if obj["pid"] == id_:
children_list.append({(obj["id"], obj["url"]): []})
return
else:
for item in children_list:
set_recursive(obj, item)
root = {(0, "/main-menu"): []}
while WIDGETS:
d = WIDGETS[0]
set_recursive(d, root)
del WIDGETS[0]
print(f"<ul>{build_HTML(root)}</ul>")
输出:
<ul><li>/main-menu<ul><li>/upload</li><li>/entry</li><li>/report<ul><li>/reppremium<ul><li>/reppremiumsum</li><li>/reppremiumfull</li></ul></li><li>/repcommission<ul><li>/repcommissionsum</li><li>/repcommissionfull</li></ul></li><li>/repportions<ul><li>/repportionssum</li><li>/repportionsfull</li></ul></li></ul></li><li>/adduser</li><li>/exportdb</li><li>/importdb</li></ul></li></ul>
解释:
在函数中,我们基本上以以下形式创建另一个数据结构:set_recursive()
{(0, '/main-menu'): [{(1, '/upload'): []},
{(2, '/entry'): []},
{(3, '/report'): [{(4, '/reppremium'): [{(5, '/reppremiumsum'): []},
{(6, '/reppremiumfull'): []}]},
{(7, '/repcommission'): [{(8, '/repcommissionsum'): []},
{(9, '/repcommissionfull'): []}]},
{(10, '/repportions'): [{(11, '/repportionssum'): []},
{(12, '/repportionsfull'): []}]}]},
{(13, '/adduser'): []},
{(14, '/exportdb'): []},
{(15, '/importdb'): []}]}
现在,这是一本元素字典,可以跟踪每个子元素。它的工作方式是,对于每个元素,它递归地检查数据结构,看看它是否能找到它的“父级”。如果找到,则属于该列表。在我们处理完之后,我们只需将其从记录中删除即可。
在函数中,您以最压缩的形式创建字符串(浏览器的解析器不在乎)。build_HTML()
此功能的要点是您需要在进入之前打开并在之后关闭它。<ul>
children_list
注意:此解决方案可以正常工作,因为数据的排序方式是,对于追加每个子项,其父项已追加。
如果呈现该字符串:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<ul><li>/main-menu<ul><li>/upload</li><li>/entry</li><li>/report<ul><li>/reppremium<ul><li>/reppremiumsum</li><li>/reppremiumfull</li></ul></li><li>/repcommission<ul><li>/repcommissionsum</li><li>/repcommissionfull</li></ul></li><li>/repportions<ul><li>/repportionssum</li><li>/repportionsfull</li></ul></li></ul></li><li>/adduser</li><li>/exportdb</li><li>/importdb</li></ul></li></ul>
</body>
该字符串的美化版本是:
<ul>
<li>/main-menu
<ul>
<li>/upload</li>
<li>/entry</li>
<li>/report<ul>
<li>/reppremium
<ul>
<li>/reppremiumsum</li>
<li>/reppremiumfull</li>
</ul>
</li>
<li>/repcommission
<ul>
<li>/repcommissionsum</li>
<li>/repcommissionfull</li>
</ul>
</li>
<li>/repportions
<ul>
<li>/repportionssum</li>
<li>/repportionsfull</li>
</ul>
</li>
</ul>
</li>
<li>/adduser</li>
<li>/exportdb</li>
<li>/importdb</li>
</ul>
</li>
</ul>
评论