【问题标题】:How to create a Bootstrap accordion from a nested dictionary in Python?如何从 Python 中的嵌套字典创建 Bootstrap 手风琴?
【发布时间】:2020-09-03 22:35:30
【问题描述】:

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

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

可以形象化为:

1
    4
       6
       7
       8
    5
2
3

我的目标是创建一个引导手风琴,就像这个链接给出的那样: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,但我对此一无所知。提前致谢。

【问题讨论】:

    标签: python twitter-bootstrap flask recursion accordion


    【解决方案1】:

    我能够在我的真正问题上达到我的结果。代码如下:

    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
    

    注意:缩进可能是关闭的。随意修复它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      相关资源
      最近更新 更多