如何从 Python 中的嵌套字典创建 Bootstrap 手风琴?
How to create a Bootstrap accordion from a nested dictionary in Python?
我有一个像这样的嵌套字典:
d = {1: {4: {6: {}, 7: {}, 8: {}}, 5: {}}, 2: {}, 3: {}}
可以形象化为:
1
4
6
7
8
5
2
3
我的目标是创建一个 bootstrap 手风琴,就像这个 link 给出的那样:https://codepen.io/glebkema/pen/QQOZRe?editors=1000
这里有截图:
为了实现我的目标,我想我可以在 python 脚本中生成 html 代码,该脚本可以使用 flask 呈现。我想出的代码是这样的:
def pretty(d, indent=0, indent_before=0):
html_code = ''
for key, value in d.items():
if indent > indent_before:
html_code += """
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
"""
elif indent == indent_before:
html_code += """
</div>
"""
else:
html_code += """
</div>
"""*indent
html_code +="""
<div class="card">
<div class="card-header" id="heading-{}">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-{}" aria-expanded="false" aria-controls="collapse-{}">
{}
</a>
</h5>
</div>
""".format(key ,key, key, key, indent)
#print('\t' * (indent) + str(key) + '({})({})\n'.format(indent,indent_before))
if isinstance(value, dict):
html_code += pretty(value, indent+1, indent)
else:
print('\t' * (indent+1) + str(value))
return html_code
msg = pretty(result)
print(msg)
基本上它是一个遍历所有字典项的递归函数。但是这段代码有 3 个我不知道如何修复的测量错误:
- 手风琴引用不会在每次添加新图层时更改
- 在每个项目之前添加一个 class="collapse" div
- 我无法正确关闭 div,因为我忘记了每个级别添加了多少项目。
我得到的输出如下:
<div class="card">
<div class="card-header" id="heading-1">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-1" aria-expanded="false" aria-controls="collapse-1">
1
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-4">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-4" aria-expanded="false" aria-controls="collapse-4">
4
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-6">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-6" aria-expanded="false" aria-controls="collapse-6">
6
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-7">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-7" aria-expanded="false" aria-controls="collapse-7">
7
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-8">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-8" aria-expanded="false" aria-controls="collapse-8">
8
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-5">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-5" aria-expanded="false" aria-controls="collapse-5">
5
</a>
</h5>
</div>
</div>
<div class="card">
<div class="card-header" id="heading-2">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-2" aria-expanded="false" aria-controls="collapse-2">
2
</a>
</h5>
</div>
</div>
<div class="card">
<div class="card-header" id="heading-3">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-3" aria-expanded="false" aria-controls="collapse-3">
3
</a>
</h5>
</div>
您能否提出一种智能而优雅的方法来从字典开始生成手风琴?你可以随意修改代码,只要我得到html代码,然后我就可以渲染了。我也想过使用 Jinja2,但我对此一无所知。提前致谢。
我能够针对我的实际问题得出结果。这是代码:
def pretty(d, indent=0, indent_previous_layer=-1, counter=0):
html_code = ''
indent_privious_item = indent_previous_layer
for key, value in d.items():
if indent > indent_privious_item and counter!=0:
html_code += """
<div id="collapse-{}" class="collapse" data-parent="#accordion-{}" aria-labelledby="heading-{}">
<div class="card-body">
<div id="accordion-{}">
""".format(counter, indent-1, counter, indent)
elif indent == indent_privious_item:
html_code += """
</div>
"""
if indent==0:
html_code += """
<!--End of Card-->
"""
elif indent < indent_privious_item:
if indent==0:
html_code += """
</div>
"""
html_code += """
</div>
</div>
</div>
</div>
"""*(indent_privious_item-indent)
html_code += """
<!--End of Card-->
"""
else:
html_code += """
</div>
"""
html_code += """
</div>
</div>
</div>
</div>
"""*(indent_privious_item-indent)
html_code +="""
<div class="card">
<div class="card-header" id="heading-{}">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-{}" aria-expanded="true" aria-controls="collapse-{}">
Depth Level {}
</a>
</h5>
</div>
<div class="card-body pb-0">
<!--h5 class="card-title"></h5-->
<p class="card-text">{}</p>
<ul class="list-group">""".format(counter+1, counter+1, counter+1, indent, "Some text")
html_code += """
</ul>
</div>
"""
if isinstance(value, dict):
code, indent_privious_item, counter = pretty(value, indent+1, indent, counter+1)
html_code += code
else:
print('\t' * (indent+1) + str(value))
return html_code, indent_privious_item, counter
注意:缩进可能有问题。随意修复它
我有一个像这样的嵌套字典:
d = {1: {4: {6: {}, 7: {}, 8: {}}, 5: {}}, 2: {}, 3: {}}
可以形象化为:
1
4
6
7
8
5
2
3
我的目标是创建一个 bootstrap 手风琴,就像这个 link 给出的那样:https://codepen.io/glebkema/pen/QQOZRe?editors=1000
这里有截图:
为了实现我的目标,我想我可以在 python 脚本中生成 html 代码,该脚本可以使用 flask 呈现。我想出的代码是这样的:
def pretty(d, indent=0, indent_before=0):
html_code = ''
for key, value in d.items():
if indent > indent_before:
html_code += """
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
"""
elif indent == indent_before:
html_code += """
</div>
"""
else:
html_code += """
</div>
"""*indent
html_code +="""
<div class="card">
<div class="card-header" id="heading-{}">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-{}" aria-expanded="false" aria-controls="collapse-{}">
{}
</a>
</h5>
</div>
""".format(key ,key, key, key, indent)
#print('\t' * (indent) + str(key) + '({})({})\n'.format(indent,indent_before))
if isinstance(value, dict):
html_code += pretty(value, indent+1, indent)
else:
print('\t' * (indent+1) + str(value))
return html_code
msg = pretty(result)
print(msg)
基本上它是一个遍历所有字典项的递归函数。但是这段代码有 3 个我不知道如何修复的测量错误:
- 手风琴引用不会在每次添加新图层时更改
- 在每个项目之前添加一个 class="collapse" div
- 我无法正确关闭 div,因为我忘记了每个级别添加了多少项目。
我得到的输出如下:
<div class="card">
<div class="card-header" id="heading-1">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-1" aria-expanded="false" aria-controls="collapse-1">
1
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-4">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-4" aria-expanded="false" aria-controls="collapse-4">
4
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-6">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-6" aria-expanded="false" aria-controls="collapse-6">
6
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-7">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-7" aria-expanded="false" aria-controls="collapse-7">
7
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-8">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-8" aria-expanded="false" aria-controls="collapse-8">
8
</a>
</h5>
</div>
<div id="collapse-1-1" class="collapse" data-parent="#accordion-1" aria-labelledby="heading-1-1">
<div class="card-body">
<div id="accordion-1-1">
<div class="card">
<div class="card-header" id="heading-5">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-5" aria-expanded="false" aria-controls="collapse-5">
5
</a>
</h5>
</div>
</div>
<div class="card">
<div class="card-header" id="heading-2">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-2" aria-expanded="false" aria-controls="collapse-2">
2
</a>
</h5>
</div>
</div>
<div class="card">
<div class="card-header" id="heading-3">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-3" aria-expanded="false" aria-controls="collapse-3">
3
</a>
</h5>
</div>
您能否提出一种智能而优雅的方法来从字典开始生成手风琴?你可以随意修改代码,只要我得到html代码,然后我就可以渲染了。我也想过使用 Jinja2,但我对此一无所知。提前致谢。
我能够针对我的实际问题得出结果。这是代码:
def pretty(d, indent=0, indent_previous_layer=-1, counter=0):
html_code = ''
indent_privious_item = indent_previous_layer
for key, value in d.items():
if indent > indent_privious_item and counter!=0:
html_code += """
<div id="collapse-{}" class="collapse" data-parent="#accordion-{}" aria-labelledby="heading-{}">
<div class="card-body">
<div id="accordion-{}">
""".format(counter, indent-1, counter, indent)
elif indent == indent_privious_item:
html_code += """
</div>
"""
if indent==0:
html_code += """
<!--End of Card-->
"""
elif indent < indent_privious_item:
if indent==0:
html_code += """
</div>
"""
html_code += """
</div>
</div>
</div>
</div>
"""*(indent_privious_item-indent)
html_code += """
<!--End of Card-->
"""
else:
html_code += """
</div>
"""
html_code += """
</div>
</div>
</div>
</div>
"""*(indent_privious_item-indent)
html_code +="""
<div class="card">
<div class="card-header" id="heading-{}">
<h5 class="mb-0">
<a role="button" data-toggle="collapse" href="#collapse-{}" aria-expanded="true" aria-controls="collapse-{}">
Depth Level {}
</a>
</h5>
</div>
<div class="card-body pb-0">
<!--h5 class="card-title"></h5-->
<p class="card-text">{}</p>
<ul class="list-group">""".format(counter+1, counter+1, counter+1, indent, "Some text")
html_code += """
</ul>
</div>
"""
if isinstance(value, dict):
code, indent_privious_item, counter = pretty(value, indent+1, indent, counter+1)
html_code += code
else:
print('\t' * (indent+1) + str(value))
return html_code, indent_privious_item, counter
注意:缩进可能有问题。随意修复它