jinja2递归循环vs字典

时间:2011-12-09 23:30:28

标签: python jinja2

我有以下字典:

{'a': {'b': {'c': {}}}}

以下的Jinja2模板:

            {% for key in dictionary recursive %}

            <li>{{ key }}
            {% if dictionary[key] %}
                <ul>{{ loop(dictionary[key]) }}</ul>
            {% endif %}
            </li>

        {% endfor %}

但Jinja2总是输出:

<ul>
    <li>a</li>
    <ul>
        <li>b</li>
    </ul>
</ul>

我的理解是使用递归,它也会向我显示“c”元素,但它仅适用于2的深度。为什么dictionary在每个循环中都不会更改为dictionary[key]迭代? dictionary始终是原始dictionary

2 个答案:

答案 0 :(得分:9)

你说得对,dictionary没有在递归调用中更新,并且循环无法继续,因为找不到密钥。

此问题的解决方法是仅使用for循环中指定的变量。在字典示例中,这意味着迭代字典的项而不仅仅是键:

from jinja2 import Template

template = Template("""                                                     
{%- for key, value in dictionary.items() recursive %}                       
  <li>{{ key }}                                                             
    {%- if value %}                                                         
      Recursive {{ key }}, {{value}}                                        
      <ul>{{ loop(value.items())}}</ul>                                     
    {%- endif %}                                                            
  </li>                                                                     
{%- endfor %}                                                               
""")

print template.render(dictionary={'a': {'b': {'c': {}}}})

此脚本的输出为:

<li>a
    Recursive a, {'b': {'c': {}}}
    <ul>
<li>b
    Recursive b, {'c': {}}
    <ul>
<li>c
</li></ul>
</li></ul>
</li>

您可以看到b键上的递归正常工作,因为keyvalue在循环的每次迭代中都会更新(我添加了“递归键,值”)消息到模板,以明确)。

答案 1 :(得分:0)

尝试这样的事情:

    {% for key in dictionary recursive %}

        <li>{{ key }}
        {% if dictionary[key] %}
            <ul>{{ loop(dictionary[key].keys()) }}</ul>
        {% endif %}
        </li>

    {% endfor %}

我认为你需要将一个iterable传递给loop()构造。