Flask - 模板
Flask – 使用 Jinja2 模板
Section titled “Flask – 使用 Jinja2 模板”虽然你可以直接从 Flask 视图函数返回 HTML 字符串,但这很快就会变得难以管理,并且将表示逻辑与应用逻辑混杂在一起。Flask 集成了强大的 Jinja2 模板引擎来解决这个问题。
相比于在 Python 中构建 HTML 字符串:
Section titled “相比于在 Python 中构建 HTML 字符串:”# Less maintainable approach# 可维护性较差的方法@app.route('/old')def old_hello(): user = 'Alice' # Embedding HTML directly in Python code # 直接在 Python 代码中嵌入 HTML return f'<html><body><h1>Hello {user}!</h1></body></html>'你可以使用 Jinja2 模板:
Section titled “你可以使用 Jinja2 模板:”-
创建带有特殊占位符的 HTML 文件(模板),用于动态内容。
-
在视图函数中使用 Flask 的
render_template()函数来渲染这些模板,并传递任何必要的数据。
render_template() 函数
Section titled “render_template() 函数”要渲染模板,你需要从 Flask 导入 render_template,并在你的视图函数中调用它,提供模板文件名以及你想以关键字参数形式传递给模板的任何变量。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/hello/<name>')def hello(name): # Renders 'templates/user_greeting.html' # 渲染 'templates/user_greeting.html' # Passes the 'name' variable from the URL to the template # 将 URL 中的 'name' 变量传递给模板 # under the variable name 'username'. # 变量名为 'username'。 return render_template('user_greeting.html', username=name)
if __name__ == '__main__': app.run(debug=True)默认情况下,Flask 在与主应用脚本或包相同的目录中查找名为 templates 的子文件夹中的模板。
/your_project app.py /templates user_greeting.html layout.html # ... other templates # ... 其他模板Jinja2 语法基础
Section titled “Jinja2 语法基础”Jinja2 模板主要是包含特殊分隔符的 HTML 文件,用于嵌入逻辑和变量:
{{ ... }}用于表达式: 用于将变量的值或表达式的结果打印到模板输出中。为了安全起见,Jinja2 会自动处理 HTML 转义。{% ... %}用于语句: 用于控制结构,如循环 (for)、条件 (if/elif/else)、模板继承 (extends、block) 和宏。{# ... #}用于注释: 用于模板引擎忽略的注释,不会出现在最终的 HTML 输出中。
模板示例(templates/user_greeting.html):
Section titled “模板示例(templates/user_greeting.html):”<!DOCTYPE html><html><head> <title>Greeting</title></head><body> {# This is a comment, it won't be rendered #} {# 这是一个注释,它不会被渲染 #}
{# Print the 'username' variable passed from Flask #} {# 打印从 Flask 传递过来的 'username' 变量 #} <h1>Hello, {{ username }}!</h1>
<p>Welcome to our application.</p> <p>欢迎来到我们的应用。</p></body></html>运行上面的示例,并访问 /hello/Bob,会渲染出这个 HTML,并将 {{ username }} 替换为 Bob。
模板中的控制结构
Section titled “模板中的控制结构”你可以在 {% ... %} 块中使用类似 Python 的控制结构。
条件语句(if/elif/else)
Section titled “条件语句(if/elif/else)”Flask 代码:
Section titled “Flask 代码:”@app.route('/grade/<int:score>')def show_grade(score): return render_template('grade_result.html', marks=score)模板(templates/grade_result.html):
Section titled “模板(templates/grade_result.html):”<!DOCTYPE html><html><body> <h1>Exam Result</h1> <h1>考试结果</h1> {% if marks >= 90 %} <p>Grade: A</p> <p>等级:A</p> {% elif marks >= 75 %} <p>Grade: B</p> <p>等级:B</p> {% elif marks >= 60 %} <p>Grade: C</p> <p>等级:C</p> {% else %} <p>Grade: F - Please see instructor.</p> <p>等级:F - 请联系教师。</p> {% endif %}</body></html>循环(for)
Section titled “循环(for)”Flask 代码:
Section titled “Flask 代码:”@app.route('/items')def show_items(): item_list = ['Apple', 'Banana', 'Cherry'] return render_template('item_list.html', items=item_list)模板(templates/item_list.html):
Section titled “模板(templates/item_list.html):”<!DOCTYPE html><html><body> <h1>Available Items</h1> <h1>可用物品:</h1> {% if items %} <ul> {% for item in items %} <li>{{ item }}</li> {% endfor %} </ul> {% else %} <p>No items available.</p> <p>暂无可用物品。</p> {% endif %}</body></html>Jinja2 最强大的功能是模板继承。它允许你定义一个基础布局模板(例如,layout.html),包含通用元素(页头、页脚、导航),并定义子模板可以覆盖的特定块。
基础模板(templates/layout.html):
Section titled “基础模板(templates/layout.html):”<!DOCTYPE html><html><head> <title>{% block title %}My Application{% endblock %}</title> <title>{% block title %}我的应用{% endblock %}</title> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"></head><body> <header> <h1>My Website</h1> <h1>我的网站</h1> </header> <main> {% block content %} {# Child templates will put their content here #} {# 子模板会将它们的内容放在这里 #} {% endblock %} </main> <footer> <p>© 2023 Me</p> <p>© 2023 我</p> </footer></body></html>子模板(更新后的 templates/user_greeting.html):
Section titled “子模板(更新后的 templates/user_greeting.html):”{% extends 'layout.html' %}
{% block title %}Greeting for {{ username }}{% endblock %}{% block title %}问候 {{ username }}{% endblock %}
{% block content %} <h2>Hello, {{ username }}!</h2> <h2>你好,{{ username }}!</h2> <p>Welcome to our application.</p> <p>欢迎来到我们的应用。</p>{% endblock %}当渲染 user_greeting.html 时,Jinja2 将:
- 加载
layout.html。 - 将
layout.html中的{% block title %}替换为user_greeting.html中{% block title %}的内容。 - 将
layout.html中的{% block content %}替换为user_greeting.html中{% block content %}的内容。
这促进了代码重用,并使得在整个应用中保持一致的外观和感觉变得容易得多。