如何在Flask/Jinja2中展示嵌套分类?
解决Flask/Jinja2中嵌套分类的显示问题
问题根源
你当前的模板代码硬编码了三层循环结构,只能处理最多三级分类,但你的数据里存在四级分类(Root -> A -> B -> C),这种写法无法适配任意深度的嵌套分类,导致显示异常。
解决方案:使用Jinja2宏实现递归渲染
Jinja2支持宏的递归调用,这是处理嵌套结构的最佳方式,能自动适配任意层级的分类。
方案一:简化后端+递归宏(推荐)
你的Category模型已经定义了backref='children',可以直接利用这个关联关系简化后端代码,无需手动构建树形结构:
后端代码调整
@app.route('/categories') def show_categories(): # 直接获取所有顶级分类(parent为None) root_categories = Category.select().where(Category.parent.is_null()) return render_template('categories.html', categories=root_categories)
Jinja2模板代码
{% macro render_category(category) %} <li> {{ category.name }} {% if category.children %} <ul> {% for child in category.children %} {{ render_category(child) }} {% endfor %} </ul> {% endif %} </li> {% endmacro %} <ul> {% for category in categories %} {{ render_category(category) }} {% endfor %} </ul>
方案二:适配原有树形结构的递归宏
如果你想保留原有的build_category_tree函数返回的树形结构,只需要调整宏的参数和访问逻辑:
Jinja2模板代码
{% macro render_category_tree(node) %} <li> {{ node.category.name }} {% if node.children %} <ul> {% for child_node in node.children %} {{ render_category_tree(child_node) }} {% endfor %} </ul> {% endif %} </li> {% endmacro %} <ul> {% for node in categories %} {{ render_category_tree(node) }} {% endfor %} </ul>
效果验证
用你的数据库数据,最终会渲染出如下嵌套结构:
- Root
- A
- B
- C
- B
- A
- root2
不管分类嵌套多少层,都能自动正确展开显示。
内容的提问来源于stack exchange,提问作者gogomaster
相关产品推荐
相关产品推荐

