Flask/Jinja2 - Iterating over nested dictionaries

10,232

Solution 1

By using the recursive modifier of the for loop (example taken from the docs):

<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

Here is something I came up with:

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)

Output:

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

(The dashes in the Jinja2 code (e.g. {%- ... -%} are for whitespace control. Play around with that.)

Solution 2

Why not just a nested for loop?

in your views.py:

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

in your index.html:

{% for key1,val in context.items %}
    <p> {{ key1 }} </p>
    <ul>
    {% for key2 in val.items %}
            <li> {{key2}} </li>
    {% endfor %}
    </ul>
{% endfor %}
Share:
10,232
removekebab
Author by

removekebab

Updated on June 04, 2022

Comments

  • removekebab
    removekebab almost 2 years

    I'm trying to display the contents and structure of a dictionary in the form of a bunch of nested un-ordered lists.

    The data that I've managed to pull together looks like this,

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

    which represents this directory tree,

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

    How would I go about iterating over this using the Jinja2 Syntax? Is there a better way go about doing this?

    Thanks in advace.

    EDIT: I feel stupid. After searching for a solution again I discovered exactly what I was looking for. Guess my google-fu wasn't really with me the first try. Here it is...