在Django中,我们如何在模板中迭代[[1,[2,[3]],[4,[]]],[2,[3]]]
之类的内容。
请注意,以上只是一个随机的例子。列表的每个元素可以在其中进一步包含任意数量的嵌套列表。我想遍历内部的每个值,并且还想知道什么是父级,以便我们可以适当地设置HTML的样式。
虽然有一种方法可以通过递归在视图中生成HTML并在模板中使用相应的变量,但这会使django模板和视图依赖,这是不需要的(loose coupling principle)。使用视图的一个示例是here,但模板系统本身的表示将优于此类实现。
答案 0 :(得分:1)
Django模板不是为处理复杂逻辑而设计的
例如,您 无法 使用include
标记来编写嵌套逻辑:
# foo.html
{% if nodes|iterable %}
<ul>
{% for x in nodes %}
{% include "foo.html" with nodes=x %}
{% endfor %}
</ul>
{% else %}
<li>{{ nodes }}</li>
{% endif %}
因为Django模板节点在渲染之前会被解析和编译,并且上面代码的编译可能会陷入循环并且通过达到最大递归深度而失败。
通常情况下,就像{% nested nodes %}
一样,模板标签就像一个视图,但属于Django模板的范围,就是你所需要的。
此外,您可以通过过滤器将数据转换为平面数据,然后轻松循环:
{% for x in nodes|nested_to_flat %}
{% if x.start_nodes %}<ul>{% endif %}
{% if x.end_nodes %}</ul>{% endif %}
{% if x.start_node %}<li>{% endif %}
{% if x.end_node %}</li>{% endif %}
{% if x.is_data %}{{ x.data }}{% endif %}
{% endfor %}
# nested_to_flat
@register.filter
def nested_to_flat(nodes):
if isinstance(nodes, list):
yield {'start_nodes': True}
for node in nodes:
yield {'start_node': True}
for i in nested_to_flat(node):
yield i
yield {'end_node': True}
yield {'end_nodes': True}
else:
yield {'data': nodes, 'is_data': True}
这类似于渲染mptt树或线程注释的想法。
答案 1 :(得分:0)
如上所述,django-mptt中提到的是一个预先制定的解决方案,它应该非常适合您的问题。
如果您想推送自己的模板标签,可以查看django文档中的custom template tags。
一些提示: