Python 现代开发学习笔记

(七)把 Python 数据交给 Jinja

先不用数据库,用两本已经会写的字典生成阅读列表。

# 项目文件:demos/template_demo.py
# 把用户文本传入模板变量,观察自动转义怎样把标签作为普通文字显示。
from flask import Flask, render_template

app = Flask(__name__)


@app.get("/")
def index():
    books = [
        {"title": "Python 入门", "finished": False},
        {"title": "NumPy 实践", "finished": True},
    ]
    return render_template("sample.html", username="reader", books=books)


if __name__ == "__main__":
    page = app.test_client().get("/")
    print(page.status_code)
    print("Python 入门" in page.text, "已读" in page.text)
<!-- 项目文件:demos/templates/sample.html -->
<!doctype html>
<html lang="zh-CN"><meta charset="utf-8"><title>阅读列表</title>
<h1>{{ username }} 的书架</h1>
<ul>
{% for book in books %}
  <li>{{ loop.index }}. {{ book.title }}:{% if book.finished %}已读{% else %}未读{% endif %}</li>
{% else %}
  <li>还没有保存书籍。</li>
{% endfor %}
</ul>
</html>

render_template("sample.html", username=..., books=...) 到当前应用的 templates 目录查找文件,把参数放进模板上下文。Jinja 展开循环和判断后得到完整 HTML,浏览器收到的是展开后的页面,不会再运行这些模板语句。

模板写法 在这份页面中的动作
{{ username }} 输出当前变量
{% for book in books %} 逐本处理列表
book.title 读取字典中的 title 键
{% if book.finished %} 根据布尔值选择已读或未读
loop.index 取得从 1 开始的循环编号
for 后的 else 列表没有任何项时显示提示

Python 传入两本书,模板先输出 reader,第一轮得到“1. Python 入门:未读”,第二轮得到“2. NumPy 实践:已读”,最终成为两个 <li>。这里的 book.title 是 Jinja 对字典与属性的查找写法,Python 代码本身仍然用 book["title"] 读取这个字典。

用两本具体书籍逐轮展开 Jinja 循环和 if,生成两个列表项,再把已经生成的 HTML 交给浏览器

{{ ... }} 负责输出,{% ... %} 负责控制,{# ... #} 是不会进入最终 HTML 的模板注释。.html 模板中的文本默认自动转义,后面会用带尖括号的真实书名核对。模板语法可查 Jinja 模板文档。

笔记正文与全部题解 · Ctrl / ⌘ K