Flask(8)- jinja2 模板入门

前言

  • 之前的文章有个栗子,视图函数可以直接返回一段 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:  //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:  //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 请参考 //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>