Skip to main content
 首页 » 编程设计

python之Django 模板迭代嵌套列表

2025年05月04日30cmt

在 Django 中,我们如何为 [[1,[2,[3]],[4,[]]],[2,[3]]].

请注意,以上只是一个随机示例。 list 的每个元素内部可以有任意数量的嵌套列表。我想遍历其中的每个值,并了解父级是什么,以便我们可以适本地设置 HTML 的样式。

虽然有一种方法可以通过递归在 View 本身中生成 HTML 并在模板中使用相应的变量,但这会使 django 模板和 View 依赖,这是不需要的(loose coupling principle)。使用 View 的一个例子是 here但是模板系统本身的表示会比这种类型的实现更好。

请您参考如下方法:

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 %}的模板标签就足够了,它的作用类似于 View ,但属于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 树或线程评论的想法。