如何在Jinja2中递归使用模板渲染Python树形结构为HTML列表
实现方案
完全可以用Jinja2的递归宏实现这个需求,下面是具体步骤:
1. 修正Python代码的笔误
你提供的Node类里属性名写错了:neghbors应该改成neighbors,否则无法正确获取子节点;另外你创建grand_child2时名字重复写成了grand_child1,也一并修正。修正后的代码:
from typing import Optional, Iterable class Node: def __init__(self, name: str, neighbors: Optional[Iterable[Node]] = None) -> None: self.name = name self.neighbors = neighbors or [] grand_child1 = Node("grand_child1") grand_child2 = Node("grand_child2") child = Node("child", [grand_child1, grand_child2]) root = Node("root", [child])
2. Jinja2递归模板写法
创建模板文件(比如tree_template.html),用Jinja2的macro定义递归渲染逻辑:
{% macro render_node(node) %} <li>{{ node.name }}</li> {% if node.neighbors %} <ul> {% for child_node in node.neighbors %} {{ render_node(child_node) }} {% endfor %} </ul> {% endif %} {% endmacro %} <ul> {{ render_node(root) }} </ul>
3. Python端渲染模板
用Jinja2环境加载模板并传入root节点:
from jinja2 import Environment, FileSystemLoader # 加载模板所在目录 env = Environment(loader=FileSystemLoader('.')) template = env.get_template('tree_template.html') # 渲染模板并传入根节点 html_output = template.render(root=root) # 输出或保存结果 print(html_output)
最终输出效果
运行后生成的HTML结构与预期一致(缩进可能略有差异,但层级结构正确):
<ul> <li>root</li> <ul> <li>child</li> <ul> <li>grand_child1</li> <li>grand_child2</li> </ul> </ul> </ul>
核心逻辑说明
- 用
macro定义可复用的render_node函数,接收单个Node对象 - 先渲染当前节点的
<li>标签,再判断是否存在子节点:如果有,就生成<ul>容器,遍历子节点并递归调用render_node - 最外层用
<ul>包裹根节点的渲染结果,完成整个树形结构的生成
内容的提问来源于stack exchange,提问作者Sadegh Moayedizadeh
相关产品推荐
相关产品推荐

