如何在Django模板中渲染树形结构(递归)?
我在内存中有一个树形结构,想用Django模板把它显示成HTML。
class Node():
name = "node name"
children = []
这里会有一个对象叫做 root
,它是一个 Node
(节点),而 children
是一个包含多个 Node
的列表。这个 root
会在模板的内容中传递过来。
我找到了一篇关于如何实现这个的讨论,链接在这里 this,但发帖的人提到在生产环境中这样做可能不太好。
有没有人知道更好的方法呢?
10 个回答
50
我来得太晚了。
你们都用了太多不必要的 with 标签,这里是我做递归的方法:
在“主”模板中:
<!-- lets say that menu_list is already defined -->
<ul>
{% include "menu.html" %}
</ul>
然后在 menu.html
中:
{% for menu in menu_list %}
<li>
{{ menu.name }}
{% if menu.submenus|length %}
<ul>
{% include "menu.html" with menu_list=menu.submenus %}
</ul>
{% endif %}
</li>
{% endfor %}
85
使用 with
模板标签,我可以创建树形/递归列表。
示例代码:
主模板:假设 'all_root_elems' 是一个包含一个或多个树根的列表
<ul>
{%for node in all_root_elems %}
{%include "tree_view_template.html" %}
{%endfor%}
</ul>
tree_view_template.html 渲染嵌套的 ul
和 li
,并使用 node
模板变量,如下所示:
<li> {{node.name}}
{%if node.has_childs %}
<ul>
{%for ch in node.all_childs %}
{%with node=ch template_name="tree_view_template.html" %}
{%include template_name%}
{%endwith%}
{%endfor%}
</ul>
{%endif%}
</li>
29
我觉得最简单的答案就是:“别这么做”。
你应该考虑在你的 视图 代码中把事情理清楚,这样就可以简单地在模板中逐个处理缩进和取消缩进。我想我会在遍历树的时候,把缩进和取消缩进的内容添加到一个列表中,然后把这个“旅行日志”列表传给模板。这样,模板就可以根据这个列表插入 <li>
和 </li>
,从而创建出递归的结构。
我也很确定,递归地包含模板文件其实是一种 错误 的做法……