在 flask 中结合 jinja2 模板引擎返回渲染后的 html 是核心功能之一。以下是详细实现方法和最佳实践:
一、基础模板渲染
1. 项目结构准备
myapp/
├── app.py # flask主程序
├── templates/ # 模板目录
│ └── index.html # jinja2模板
└── static/ # 静态资源(css/js/图片)
2. 基本渲染示例
# app.py from flask import flask, render_template app = flask(__name__) @app.route('/') def home(): return render_template('index.html', title='首页', user={'name': '张三', 'age': 25})
<!-- templates/index.html --> <!doctype html> <html> <head> <title>{{ title }}</title> <link href="{{ url_for('static', filename='css/style.css') }}" rel="external nofollow" rel="stylesheet"> </head> <body> <h1>欢迎, {{ user.name }}!</h1> {% if user.age >= 18 %} <p>您是成年人</p> {% else %} <p>您是未成年人</p> {% endif %} </body> </html>
二、高级模板技巧
1. 模板继承(layout系统)
<!-- templates/layout.html --> <html> <head> {% block head %} <title>{% block title %}{% endblock %}</title> {% endblock %} </head> <body> {% block content %}{% endblock %} </body> </html>
<!-- templates/page.html --> {% extends "layout.html" %} {% block title %}子页面{% endblock %} {% block content %} <h1>这是子页面内容</h1> {% endblock %}
2. 宏(macros)实现组件复用
<!-- templates/macros.html --> {% macro render_user(user) %} <div class="user-card"> <h3>{{ user.name }}</h3> <p>年龄: {{ user.age }}</p> </div> {% endmacro %}
<!-- 使用宏 --> {% from "macros.html" import render_user %} {{ render_user({'name': '李四', 'age': 30}) }}
三、动态数据与js交互
1. 直接传递json到js
# flask路由 @app.route('/data') def get_data(): return render_template('data.html', items=[1, 2, 3], config={'debug': true})
<script> const app_config = {{ config | tojson | safe }}; const items = {{ items | tojson | safe }}; console.log(app_config.debug); // true items.foreach(item => console.log(item)); </script>
2. ajax动态加载(推荐)
# 提供json api @app.route('/api/data') def api_data(): return jsonify({'data': [4,5,6]})
// 前端通过fetch获取 fetch('/api/data') .then(res => res.json()) .then(data => { document.getelementbyid('output').innerhtml = `服务器数据: ${data.data.join(', ')}`; });
四、常见问题解决方案
1. 缓存问题
开发时禁用缓存:
@app.after_request def add_header(response): if 'cache-control' not in response.headers: response.headers['cache-control'] = 'no-store' return response
2. 处理表单数据
@app.route('/submit', methods=['post']) def submit(): username = request.form.get('username') return render_template('result.html', username=username)
<form method="post" action="/submit"> <input type="text" name="username"> <button type="submit">提交</button> </form>
五、性能优化建议
1.模板缓存(生产环境启用):
app.config['templates_auto_reload'] = false # 生产环境设为false
2.静态文件版本控制:
<link href="/static/css/style.css?v={{ config.version }}" rel="external nofollow" rel="stylesheet">
3.异步加载:
<script defer src="{{ url_for('static', filename='js/app.js') }}"></script>
六、安全注意事项
1.始终转义变量:
<!-- 安全 --> <p>{{ user_input | escape }}</p> <!-- 危险!避免直接渲染html --> <p>{{ user_input | safe }}</p>
2.内容安全策略(csp):
@app.after_request def add_csp(response): response.headers['content-security-policy'] = "default-src 'self'" return response
七、完整工作流程示例
# app.py from flask import flask, render_template, request app = flask(__name__) @app.route('/search') def search(): query = request.args.get('q', '') results = [] # 这里替换为实际搜索逻辑 return render_template('search.html', query=query, results=results) if __name__ == '__main__': app.run(debug=true)
<!-- templates/search.html --> {% extends "layout.html" %} {% block content %} <form action="/search"> <input type="text" name="q" value="{{ query }}"> <button>搜索</button> </form> <ul> {% for item in results %} <li>{{ item }}</li> {% endfor %} </ul> {% endblock %}
通过以上方法,您可以高效地在flask中实现:
- 动态html渲染
- 前后端数据交互
- 组件化开发
- 安全的内容输出
关键点是合理使用jinja2的模板继承、控制结构和过滤器,同时注意安全性和性能优化。
到此这篇关于flask如何结合jinja2模板引擎返回渲染后html的文章就介绍到这了,更多相关flask jinja2返回渲染后html内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论