Flask反向布局模式:从多组件/模板构建单页的实现方法
实现方案
有两种常用的实现方式,可根据你的业务场景选择:
方案1:视图层预渲染子模板
你原本的思路可以直接复用,只需要在模板输出时增加safe过滤器避免HTML被转义即可。这种方案适合需要为每个子模板传入独立参数的场景。
视图层代码:
@app.route('/') def index(): # 可根据客户配置、权限等逻辑动态生成需要加载的视图列表 view_config = [ ('view1.html', {"title": "模块1", "data": [1,2,3]}), ('view2.html', {"title": "模块2", "data": [4,5,6]}), ('view3.html', {"title": "模块3", "data": [7,8,9]}), ] # 逐个预渲染子模板,拿到渲染后的HTML字符串 rendered_views = [render_template(tpl, **params) for tpl, params in view_config] return render_template('index.html', rendered_views=rendered_views)
index.html模板代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>动态组合页面</title> </head> <body> {% for view_html in rendered_views %} <!-- safe过滤器告诉Jinja2这段内容是安全的HTML,不需要转义 --> {{ view_html|safe }} {% endfor %} </body> </html>
方案2:模板层动态引入子模板
Jinja2的{% include %}语法本身支持传入变量作为模板路径,你可以直接把要加载的模板文件名列表传到模板层,由模板完成动态引入,代码更简洁。
视图层代码:
@app.route('/') def index(): # 直接传递需要加载的模板文件名列表,可根据业务逻辑动态调整 view_templates = ['view1.html', 'view2.html', 'view3.html'] return render_template('index.html', view_templates=view_templates)
index.html模板代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>动态组合页面</title> </head> <body> {% for tpl in view_templates %} {% include tpl %} <!-- 如果需要给当前引入的子模板传单独参数,可搭配with语句使用 --> <!-- {% with custom_param = loop.index %} {% include tpl %} {% endwith %} --> {% endfor %} </body> </html>
方案选择建议
- 若子模块需要独立的渲染参数、或需要在视图层做权限校验判断是否加载某个模块,选方案1
- 若子模块逻辑简单、不需要独立传参,选方案2更简洁
内容的提问来源于stack exchange,提问作者save_jeff
相关产品推荐
相关产品推荐

