繁体   English   中英

Flask / Jinja2-迭代嵌套字典

[英]Flask/Jinja2 - Iterating over nested dictionaries

我试图以一堆嵌套的无序列表的形式显示字典的内容和结构。

我设法整理的数据看起来像这样,

{'.': {'walk.py': None, 'what.html': None, 'misc': {}, 'orders': {'order1.html':  None, 'more': {'stuff.html': None}}}}

代表这个目录树,

.:
misc/  orders/  walk.py  what.html

./misc:

./orders:
more/  order1.html

./orders/more:
stuff.html

我将如何使用Jinja2语法对此进行迭代? 是否有更好的方法可以做到这一点?

非常感谢。

编辑:我感到愚蠢。 再次寻找解决方案后,我确切地找到了我想要的东西。 猜猜我的google-fu并不是第一次尝试。 这里是...

通过使用for循环recursive修饰符(取自文档的示例):

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>

更新

这是我想到的:

from jinja2 import Template

x = Template("""{%- for key, value in tree.iteritems() recursive %}
{{ '--' * (loop.depth-1) }}{{ key }}
{%- if value is mapping -%}/{{ loop(value.iteritems()) }}{%- endif -%}
{%- endfor %}
""")

tree = {'.': {
    'walk.py': None,
    'what.html': None,
    'misc': {},
    'orders': {
        'order1.html': None,
        'more': {
            'stuff.html': None
        }
    }
}}

print x.render(tree=tree)

输出:

./
--walk.py
--what.html
--misc/
--orders/
----order1.html
----more/
------stuff.html

(Jinja2代码中的破折号(例如{%- ... -%} -...- {%- ... -%}用于空格控制 。请尝试一下。)

为什么不只是嵌套的for循环?

在您的views.py中:

def index(request):
    context={'main1':{'sub1','sub2','sub3'},'main2':{'sub1','sub2'}}
    return render(request,'index.html',context)

在您的index.html中:

{% for key1,val in context.items %}
    <p> {{ key1 }} </p>
    <ul>
    {% for key2 in val.items %}
            <li> {{key2}} </li>
    {% endfor %}
    </ul>
{% endfor %}

首先整理数据:

a = {'.': {'walk.py': None, 'what.html': None, 'misc': {}, 'orders': {'order1.html':  None, 'more': {'stuff.html': None}}}}    

from collections import defaultdict

def f(data, path):
    for k,v in data.iteritems():
        if v is None:
            yield path,k
        else:
            yield path,k+"/"
            for k in f(v,path+k+"/"):
                yield k

def process_data():
    collect = defaultdict(list)
    for p in f(a,""):
        if p[0]:
            collect[p[0][:-1]].append(p[1])
    return collect

现在,如果您运行:

data = process_data()
for k in data.keys():
    print k,data[k]

你得到:

./orders ['order1.html', 'more/']
./orders/more ['stuff.html']
. ['walk.py', 'what.html', 'misc/', 'orders/']

多数民众赞成在您需要渲染。 模板应类似于:

{% for k in sitemap.keys()|sort -%}
    {{ k }}:<br/>
    {% for v in sitemap[k] %}
    {{ v }}
    {%- endfor %}
    <br/>
{%- endfor %}

以及渲染请求:

@app.route("/")
def hello():
    return render_template('temp.html',sitemap=process_data())

在我的测试中呈现为:

.:<br/>    
walk.py
what.html
misc/
orders/
<br/>./orders:<br/>    
order1.html
more/
<br/>./orders/more:<br/>    
stuff.html
<br/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM