如何使用Python中的嵌套字典创建Bootstrap手风琴? [英] How to create a Bootstrap accordion from a nested dictionary in Python?

查看:66
本文介绍了如何使用Python中的嵌套字典创建Bootstrap手风琴?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的嵌套字典:

  d = {1:{4:{6:{},7:{},8:{}},5:{}},2:{},3:{}} 

可以可视化为:

  1467852个3 

我的目标是创建一个类似于此链接给出的引导手风琴:

为了实现我的目标,我认为可以在可以使用flask呈现的python脚本中生成html代码.我想出的代码是这样的:

  def pretty(d,indent = 0,indent_before = 0):html_code =''对于键,值在d.items()中:如果缩进>indent_before:html_code + ="< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">"elif indent == indent_before:html_code + ="</div>"别的:html_code + ="</div>"*"缩进html_code + ="";< div class ="card">< div class ="card-header"id ="heading-{}">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =" #collapse-{}"aria-expanded =假"aria-controls ="collapse-{}">{}</a></h5></div>" .format(键,键,键,键,缩进)#print('\ t'*(缩进)+ str(key)+'({})({})\ n'.format(indent,indent_before))如果isinstance(value,dict):html_code + = pretty(值,缩进+1,缩进)别的:print('\ t'*(缩进+1)+ str(值))返回html_code味精=漂亮(结果)打印(味精) 

基本上,这是一个递归函数,它遍历所有字典项.但是这段代码有3个测量错误,我不知道如何解决:

  • 手风琴引用不会在每次添加新图层时更改
  • 一个类=折叠"div被添加到每个项目之前
  • 我无法正确关闭div,因为我无法跟踪到每个级别添加了多少项目.

我得到的输出如下:

 < div class ="card">< div class ="card-header"id ="heading-1">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href ="#collapse-1"aria-expanded =假"aria-controls ="collapse-1">.1个</a></h5></div>< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">< div class ="card">< div class ="card-header"id ="heading-4">.< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href ="#collapse-4"aria-expanded =假"aria-controls ="collapse-4">.4</a></h5></div>< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">< div class ="card">< div class ="card-header"id ="heading-6">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =#collapse-6"aria-expanded =假"aria-controls ="collapse-6">.6</a></h5></div>< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">< div class ="card">< div class ="card-header"id ="heading-7">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href ="#collapse-7"aria-expanded =假"aria-controls ="collapse-7".7</a></h5></div>< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">< div class ="card">< div class ="card-header"id ="heading-8">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =&#; collapse-8"aria-expanded =假"aria-controls ="collapse-8">.8</a></h5></div>< div id ="collapse-1-1"class ="collapse"data-parent =#accordion-1"aria-labeled by ="heading-1-1"< div class =卡体">< div id ="accordion-1-1">< div class ="card">< div class ="card-header"id ="heading-5">< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =#collapse-5";aria-expanded =假"aria-controls ="collapse-5">.5</a></h5></div></div>< div class ="card">< div class ="card-header"id ="heading-2">.< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =#collapse-2";aria-expanded =假"aria-controls ="collapse-2">.2个</a></h5></div></div>< div class ="card">< div class ="card-header"id ="heading-3"< h5 class ="mb-0"><角色=按钮";data-toggle =收合"href =#collapse-3";aria-expanded =假"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对于键,值在d.items()中:如果缩进>indent_privious_item和counter!= 0:html_code + ="< div id ="collapse- {}"class ="collapse"data-parent =#accordion- {}"aria-labelledby =标题-{}">< div class =卡体">< div id ="accordion-{}">"格式.(counter,indent-1,counter,indent)elif indent == indent_privious_item:html_code + ="</div>"如果indent == 0:html_code + ="<!-卡片结尾->"Elif indent<indent_privious_item:如果indent == 0:html_code + ="</div>"html_code + ="</div></div></div></div>"" *(indent_privious_item-indent)html_code + ="<!-卡片结尾->"别的: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"><角色=按钮";data-toggle =收合"href =" #collapse-{}"aria-expanded ="true"aria-controls ="collapse-{}">深度级别{}</a></h5></div>< div class =卡体pb-0-";<!-h5 class ="card-title"</h5->< p class =卡片文字"> {}</p>< ul class =列表组""." .format(counter + 1,counter + 1,counter + 1,indent,"Some text")html_code + ="</ul></div>"如果isinstance(value,dict):代码,indent_privious_item,计数器= pretty(值,缩进+1,缩进,计数器+1)html_code + =代码别的:print('\ t'*(缩进+1)+ str(值))返回html_code,indent_privious_item,计数器 

注意:缩进可能已关闭.随时修复

I have a nested dictionary like this one:

d = {1: {4: {6: {}, 7: {}, 8: {}}, 5: {}}, 2: {}, 3: {}}

Which can be visualized as:

1
    4
       6
       7
       8
    5
2
3

My goal is to create a bootstrap accordion like the one give by this link: https://codepen.io/glebkema/pen/QQOZRe?editors=1000

Here there is a screenshot:

In order to achieve my goal I figured that I could generate the html code in a python script that can be rendered using flask. The code I came up with is this:

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)

Basically it is a recursive function that iterates through all the dictionary items. However this code has 3 measure errors which I don't know how to fix:

  • The accordion references do not change every time a new layer is added
  • A class="collapse" div is added before every item
  • I cannot close the divs correctly as I lose track of how many items have been added up to each level.

The output that I get is the following:

<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>

Would you be able to propose a smart and elegant way to generate the accordion starting from the dictionary? You can modify the code as you want as long as I get the html code that I can then render. I also thought of using Jinja2 but I have no clue about it. Thanks in advance.

解决方案

I was able to reach my result on my real problem. Here is the code:

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

Note: the indentation may be off. Feel free to fix it

这篇关于如何使用Python中的嵌套字典创建Bootstrap手风琴?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆