2014-01-08 170 views
1

我試圖以一堆嵌套的無序列表的形式顯示字典的內容和結構。Flask/Jinja2 - 迭代嵌套字典

,我已經成功地拉到一起看起來像這樣的數據,

{'.': {'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的語法在這個迭代?有沒有更好的方法去做這件事?

感謝advace。

編輯:我覺得很蠢。再次搜索解決方案後,我發現了我正在尋找的東西。猜猜我的谷歌福是不是真的與我第一次嘗試。 Here it is...

回答

7

通過使用recursive修改的for loop的(例如,從文檔拍攝):

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

UPDATE

這裏是我想出了:

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代碼中的破折號(例如, {%- ... -%}適用於whitespace control。玩的是)

+0

這將在瓶中正確的渲染工作? – removekebab

+0

用燒瓶工作得很好。謝啦。 – removekebab

+0

如果它有效,你應該接受其他人學習的答案 – codegeek

0

首先組織數據:

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