Flask(8)- jinja2 模板入门

2021-07-14 16:41:43 浏览数 (1)

前言

  • 之前的文章有个栗子,视图函数可以直接返回一段 html 代码,浏览器可以自动渲染
  • 但是当你的 HTML 非常复杂的话,也要整串写在代码里面吗,这显然不合理的,可阅读性也非常差
  • 所以,就诞生了 Jinja2 这种模板引擎来解决需要返回复杂 jinja2 模板代码的问题

简单的栗子

以下是一个 jinja2 的模板,它对登录和未登录用户显示不同的信息

代码语言:javascript复制
<html>
{% if login %}
  <p>你好,{{name}}</p>
{% else %}
  <a href='/login'>登录</a>
{% endif %}
</html>

如果用户已经登录:变量 login 为真、变量 name 为 tom,模板被渲染成如下的 html 文件

代码语言:javascript复制
<html>
  <p>你好,tom</p>
</html>

如果用户没有登录:变量 login 为假,模板被渲染成如下的 html 文件:

代码语言:javascript复制
<html>
  <a href='/login'>登录</a>
</html>

Flask 中使用模板

目录结构

一般来说 templates 就是存放模板的目录

jinja2 模板代码
代码语言:javascript复制
<!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 中的变量进行替换
代码语言:javascript复制
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 中的变量,语法如下:

代码语言:javascript复制
 {{ 变量 }}
jinja2 模板
代码语言:javascript复制
<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 代码
代码语言:javascript复制
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 循环语句,语法如下:

代码语言:javascript复制
{% for item in iterable %}
{% endfor %}

有些教程会说有另一种等价写法

代码语言:javascript复制
# for item in iterable
# endfor 

但我实验发现并不生效

jinja2 模板代码
代码语言:javascript复制
<h1>Members</h1>
<ul>
{% for user in users %}
  <li>{{ user }}</li>
{% endfor %}

# for item in iterable
  <li>{{ user }}</li>
# endfor
</ul>
Flask 代码
代码语言:javascript复制
#!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 判断语句,语法如下:

代码语言:javascript复制
{% if cond %}
{% elif cond %}
{% else %}
{% endif %} 
jinja2 模板代码
代码语言:javascript复制
<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 代码
代码语言:javascript复制
#!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 可以用来在语句里对变量或表达式进行测试,语法如下:

代码语言:javascript复制
{% 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 模板代码
代码语言:javascript复制
<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 的模板输入
代码语言:javascript复制
number = 404
string = 'HELLO'
渲染后的 html
代码语言:javascript复制
<html>
  <p> 404 is even
  <p> HELLO is upper
</html>

过滤器

语法

jinja2 过滤器的是一个函数,语法如下:

代码语言:javascript复制
{{ variable | filter }}
  • 执行函数调用 filter(varialbe),把函数返回值作为这个代码块的值
  • 暂时不举具体的栗子了,只做简单介绍,目测后面我会出详细文章讲解 jinja2
jinja2 模板
代码语言:javascript复制
<html>
{{ string | upper }}
</html>
jinja2 的模板输入
代码语言:javascript复制
string = 'hello'
渲染后的 html
代码语言:javascript复制
<html>
HELLO
</html>

0 人点赞