我以前从未使用过Jinja递归,但似乎应该可以相对理解。我在使用模板引擎渲染这种格式的数据时遇到麻烦。以下python代码是我尝试在Jinja中重现的一个很好的示例:
layers = {
'groups': {
'lower': {
'groups': {},
'layers': [{
'layer_name': 'left #1',
},
{
'layer_name': 'right #1',
}]
},
'upper': {
'groups': {},
'layers': [{
'layer_name': 'left',
},
{
'layer_name': 'right',
}]
}
},
'layers': [{
'layer_name': 'Background',
}]
}
def printDict(_dict):
for layer in _dict['layers']:
print(layer['layer_name'])
for group in _dict['groups']:
print(group)
printDict(_dict['groups'][group])
printDict(layers)
我尝试使模板代码尽可能类似于上述工作逻辑,如下所示:
<ul>
{% for node in layers recursive %}
{% set outer_loop = loop %}
{% if node == "layers" %}
{% for layer in layers[node] %}
<li>{{layer['layer_name']}}</li>
{% endfor %}
{% elif node == "groups" %}
{% for group in layers[node] %}
<li><b>{{group}}</b></li>
<ul class="submenu">
{{ outer_loop(layers[node][group]) }}
</ul>
{% endfor %}
{% endif %}
{% endfor %}
</ul>
但是,每次我都得到“超出递归深度”。调试非常令人沮丧,因为在循环期间没有任何简单的调试器或方法可以打印值。谁能发现逻辑缺陷?
答案 0 :(得分:1)
好吧,我最终想出一种可行的方法。问题在于Jinja具有非常奇怪的变量作用域。与python不同,在循环内部不会重新分配变量,而是继续使用原始的全局变量,这会导致无限循环条件。我通过在每个递归调用(和原始调用,保持一致)上使用“ .items()”方法解决了此问题,该方法在本地范围内创建了一个新变量(我相信,也许它也只是覆盖了全局范围内的变量) ,但无论哪种方法都可以)
<ul>
{% for key, v in layers,items() recursive %}
{% set outer_loop = loop %}
{% if key == "layers" %}
{% for layer in v %}
<li>{{layer['layer_name']}}</li>
{% endfor %}
{% elif key == "groups" %}
{% for group in v %}
<li><b>{{group}}</b></li>
<ul class="submenu">
{{ outer_loop(v[group].items()) }}
</ul>
{% endfor %}
{% endif %}
{% endfor %}
</ul>