Flask 模板渲染
模板是包含占位符的 HTML 文件
Flask
使用 Jinja2
模板引擎來處理模板渲染。模板渲染允許你將動態內容插入到 HTML 頁面中,使得應用能夠生成動態的網頁內容。
- 創建模板:將 HTML 文件放在 templates 文件夾中,使用 Jinja2 占位符。
- 渲染模板:使用 render_template 函數在視圖函數中渲染模板。
- 模板繼承:創建基礎模板,允許其他模板繼承和擴展。
- 控制結構:使用條件語句和循環在模板中控制邏輯。
- 過濾器:使用過濾器格式化變量數據。
- 宏和模板包含:創建和使用宏以及模板包含,提高模板的復用性。
- 安全性:Jinja2 默認對模板變量進行自動轉義以防止 XSS 攻擊。
- 模板上下文:將數據傳遞給模板,并在模板中使用這些數據。
基本概念/創建模板
模板是包含占位符的 HTML 文件。
Flask 使用 Jinja2 模板引擎來渲染這些模板,將 Python 數據插入到 HTML 中,從而生成最終的網頁。
<!DOCTYPE html>
<html>
<head><title>Welcome</title>
</head>
<body><h1>{{ title }}</h1><p>Hello, {{ name }}!</p>
</body>
</html>
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():return render_template('index.html',title='Home',name='Misha')if __name__ == '__main__':app.run(debug=True)
格式: {{ 變量名 }}
模板繼承
root.html
<!DOCTYPE html>
<html>
<head><title>{% block title %}My Website{% endblock %}</title>
</head>
<body><header><h1>My Website</h1></header><main>{% block content %}{% endblock %}</main><footer><p>Footer content</p></footer>
</body>
</html>
leaf.html
{% extends "root.html" %}{% block title %}Home Page{% endblock %}{% block content %}
<h2>Welcome to the Home Page!</h2>
<p>Content goes here.</p>
{% endblock %}
app.py
@app.route('/leaf')
def leaf():return render_template('leaf.html')
檢查響應的內容確實被替換了
格式:可替換區域 {% block 變量名 %} {% endblock %}
控制結構
Jinja2 提供了多種控制結構,用于在模板中實現條件邏輯和循環。
ctrl_flow.html
<!DOCTYPE html>
<html>
<head><title>Welcome</title>
</head>
<body><!-- 條件語句 -->{% if user %}<p>Welcome, {{ user }}!</p>{% else %}<p>Please log in.</p>{% endif %}<!-- 循環語句 --><ul>{% for item in items %}<li>{{ item }}</li>{% endfor %}</ul>
</body>
</html>
app.py
@app.route('/ctrl_flow')
def ctrl_flow():# return render_template('ctrl_flow.html',user="Zhangsan")# return render_template('ctrl_flow.html')return render_template('ctrl_flow.html',user="Zhangsan",items=['apple','banana','orange'])
傳了user
未傳user和items
傳了user和items
過濾器
過濾器用于在模板中格式化和處理變量數據。
filter.html
<!DOCTYPE html>
<html>
<head><title>Welcome</title>
</head>
<body>
<p>{{ name|capitalize }}</p>
<p>{{ price|round(2) }}</p>
</body>
</html>
app.py
@app.route('/filter')
def filter():return render_template('filter.html',name='wangwu',price=2.999)
過濾器的寫法與shell中的管道一樣都是用"|"來表示
格式: {{ 變量名|處理方法 }}
宏和模板包含
macros.html
{% macro render_item(item) %}<div><h3>{{ item.title }}</h3><p>{{ item.description }}</p></div>
{% endmacro %}
使用宏: macros_demo.html
{% from "macros.html" import render_item %}<h1>Items</h1>
{% for item in items %}{{ render_item(item) }}
{% endfor %}
app.py
@app.route('/macros')
def macros():# return render_template('macros_demo.html',items=['apple','banana','orange'])return render_template('macros_demo.html',items=[{"title":"apple","description":"蘋果"},{"title":"banana","description":"香蕉"},{"title":"orange","description":"橘子"}])
變量不正確時的效果
正常的顯示
安全性
security.html
<html>
<head> security </head>
<body>
<p>{{ user_input }}</p>
</body>
</html>
@app.route('/xss')
def xss():return render_template('security.html',user_input='<script> alert(1) </script>')
自動轉義:Jinja2 默認會對模板中的變量進行自動轉義,防止 XSS 攻擊。
<script>
標簽不會被認為是html元素
模板上下文
視圖函數中傳遞的變量成為模板的上下文,這些變量可以在模板中直接使用。
profile.html
<h1>{{ user.name }}</h1>
<p>Age: {{ user.age }}</p>
app.py
@app.route('/profile/<username>')
def profile(username):user = {'name': username, 'age': 25}return render_template('profile.html', user=user)
Demo
Flask
參考
- Flask模板渲染