前言
- 之前的文章有个栗子,视图函数可以直接返回一段 html 代码,浏览器可以自动渲染
- 但是当你的 HTML 非常复杂的话,也要整串写在代码里面吗,这显然不合理的,可阅读性也非常差
- 所以,就诞生了 Jinja2 这种模板引擎来解决需要返回复杂 jinja2 模板代码的问题
简单的栗子
以下是一个 jinja2 的模板,它对登录和未登录用户显示不同的信息
<html> {% if login %} <p>你好,{{name}}</p> {% else %} <a href='/login'>登录</a> {% endif %} </html>
如果用户已经登录:变量 login 为真、变量 name 为 tom,模板被渲染成如下的 html 文件
<html> <p>你好,tom</p> </html>
如果用户没有登录:变量 login 为假,模板被渲染成如下的 html 文件:
<html> <a href='/login'>登录</a> </html>
Flask 中使用模板
目录结构
一般来说 templates 就是存放模板的目录
jinja2 模板代码
<!DOCTYPE html> <html> <body> <h2>My name is {{ name }}, I am {{ age }} years old</h2> </body> </html>
flask 代码
- 首先,需要 import render_template
- 然后,视图函数调用 render_template,对模板 templates/index.html 进行渲染
- render_template 包含有 2 个命名参数:name 和 age,模板引擎将模板 templates/index.html 中的变量进行替换
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html', name='tom', age=10) app.run(debug=True)
浏览器的运行效果
分界符
jinja2 模板文件混合 html 语法与 jinja2 语法,使用分界符区分 html 语法与 jinja2 语法。有 5 种常见的分界符:
- {{ 变量 }},将变量放置在 {{ 和 }} 之间;
- {% 语句 %},将语句放置在 {% 和 %} 之间;
- {# 注释 #},将注释放置在 {# 和 #} 之间;
- ## 注释,将注释放置在 # 之后
变量
语法
jinja2 模板中,使用 {{ var }} 包围的标识符称为变量,模板渲染会将其替换为 Python 中的变量,语法如下:
{{ 变量 }}
jinja2 模板
<html> {{ string }} <ul> <li> {{ list[0] }} <li> {{ list[1] }} <li> {{ list[2] }} <li> {{ list[3] }} </ul> <ul> <li> {{ dict['name'] }} <li> {{ dict['age'] }} </ul> </html>
包含有 3 种类型的变量:字符串、列表、字典,它们会被替换为同名的 Python 变量
flask 代码
from flask import Flask, render_template app = Flask(__name__) string = 'www.imooc.com' list = ['www', 123, (1, 2, 3), {"name": "poloyy"}] dict = {'name': 'zhangsan', 'age': True} @app.route('/2') def index2(): return render_template('index2.html', string=string, list=list, dict=dict) app.run(debug=True)
列表的值包含字符串、数字、元组、字典,字典的值包含字符串、布尔值
浏览器的运行效果
for 语句
语法
jinja2 模板中,使用 {% 语句 %} 包围的语法块称为语句,jinja2 支持类似于 Python 的 for 循环语句,语法如下:
{% for item in iterable %} {% endfor %}
有些教程会说有另一种等价写法
# for item in iterable # endfor
但我实验发现并不生效
jinja2 模板代码
<h1>Members</h1> <ul> {% for user in users %} <li>{{ user }}</li> {% endfor %} # for item in iterable <li>{{ user }}</li> # endfor </ul>
Flask 代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/11 6:04 下午 # file: 6_jinja2.py """ from flask import Flask, render_template app = Flask(__name__) users = ['tom', 'jerry', 'mike'] @app.route('/3') def index3(): return render_template('index3.html', users=users, iterable=users) app.run(debug=True)
浏览器的运行效果
能看到 # for 的写法并没有生效
if 语句
语法
jinja2 模板中,使用 {% 语句 %} 包围的语法块称为语句,jinja2 支持类似于 Python 的 if-else 判断语句,语法如下:
{% if cond %} {% elif cond %} {% else %} {% endif %}
jinja2 模板代码
<html> {% if a %} <p>a is True</p> {% else %} <p>a is False</p> {% endif %} {% if b %} <p>b is True</p> {% elif c %} <p>b is False, and c is True</p> {% endif %} </html>
Flask 代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/11 6:04 下午 # file: 6_jinja2.py """ from flask import Flask, render_template app = Flask(__name__) @app.route('/4') def index4(): a = False b = False c = True return render_template('index4.html', a=a, b=b, c=c) app.run(debug=True)
浏览器的运行效果
tests
语法
jinja2 提供的 tests 可以用来在语句里对变量或表达式进行测试,语法如下:
{% variable is test %}
完整的 test 请参考 https://jinja.palletsprojects.com/en/latest/templates/#builtin-tests,部分的 test 如下:
test 名称 | 功能 |
---|---|
defined | 变量是否已经定义 |
boolean | 变量的类型是否是 boolean |
integer | 变量的类型是否是 integer |
float | 变量的类型是否是 float |
string | 变量是否是 string |
mapping | 变量的类型是否是字典 |
sequence | 变量的类型是否是序列 |
even | 变量是否是偶数 |
odd | 变量是否是奇数 |
lower | 变量是否是小写 |
upper |
变量是否是大写 |
jinja2 模板代码
<html> {% if number is odd %} <p> {{ number }} is odd {% else %} <p> {{ number }} is even {% endif %} {% if string is lower %} <p> {{ string }} is lower {% else %} <p> {{ string }} is upper {% endif %} </html>
jinja2 的模板输入
number = 404 string = 'HELLO'
渲染后的 html
<html> <p> 404 is even <p> HELLO is upper </html>
过滤器
语法
jinja2 过滤器的是一个函数,语法如下:
{{ variable | filter }}
- 执行函数调用 filter(varialbe),把函数返回值作为这个代码块的值
- 暂时不举具体的栗子了,只做简单介绍,目测后面我会出详细文章讲解 jinja2
jinja2 模板
<html> {{ string | upper }} </html>
jinja2 的模板输入
string = 'hello'
渲染后的 html
<html> HELLO </html>