一、基本用法 |
||
1 |
模板引擎的理解 |
|
2 |
定界符 |
(语句、表达式、注释、支持".") |
3 |
模板语法 |
(支持大部分Python对象)、运算符号、比较符号、逻辑符号、以及in、is、None、布尔值(Ture;False) |
4 |
if 语法 |
|
5 |
for 语法 |
|
6 |
常用特殊变量 |
loop.index、 loop.index0、loop.length 等 |
7 |
渲染模板 |
render_template() |
8 |
传入变量类型 |
可以是字符串、列表和字典,也可以是函数、类和类实例,这完全取决于你在视图函数传入的值。 |
二、辅助工具 |
|
|
9 |
在模板中定义变量 |
使用set标签 |
10 |
Flask内置上下文变量 |
config、request、session、g |
11 |
自定义上下文 |
Flask提供了一个app.context_processor装饰器 |
|
全局对象 |
|
12 |
内置全局对象 |
常用的三个range([start,] stop [,step]) Lipsum(n=5,html=True,min=20,max=100) dict(**items) |
13 |
自定义全局函数
|
使用app.template_global装饰器直接将函数注册为模板全局函数。 |
|
过滤器 |
|
14 |
基本用法 |
| 、叠加 |
15 |
语块过滤 |
|
16 |
常用内置过滤器 |
|
17 |
tojson |
Flask内置过滤器 |
18 |
自定义过滤器 |
使用app.template_filter()装饰器 |
1、模板引擎:
模板引擎的作用就是读取并执行模板中的特殊语法标记,并根据传入的数据将变量替换为实际值,输出最终的HTML页面,这个过程被称为渲染(rendering)。Flask默认使用的模板引擎是Jinja2。
2、定界符
(1)语句 比如if判断、for循环等: {% ... %}
(2)表达式 比如字符串、变量、函数调用等 {{ … }}
(3)注释 {#...#}
(4)支持使用“.” 获取变量的属性。如user.username等同于 user[‘username’]
3、模板语法
(1)Jinja2允许你在模板中使用大部分Python对象,比如字符串、列表、字典、元组、整型、浮点型、布尔值。它支持基本的运算符号(+、-、*、/等)、比较符号(比如==、!=等)、逻辑符号(and、or、not和括号)以及in、is、None和布尔值(True、False)。
(2) if 语法
{% if user.bio %} {{ user.bio }} {% else %} This user has not provided a bio. {% endif %} |
(3)for语法
Members
{% for user in users %}
{% endfor %} |
{% for key, value in my_dict.iteritems() %}
{% endfor %} |
常用的Jinja2 for循环特殊变量
http://jinja.pocoo.org/docs/2.10/templates/#for
loop.index |
循环迭代计数(从1开始) |
loop.index0 |
循环迭代计数(从0开始) |
loop.revindex |
循环迭代倒序计数(从len开始,到1结束) |
loop.revindex0 |
循环迭代倒序计数(从len-1开始,到0结束) |
loop.first |
是否为循环的第一个元素 |
loop.last |
是否为循环的最后一个元素 |
loop.length |
循环序列中元素的个数 |
loop.cycle |
在给定的序列中轮循,如上例在”odd”和”even”两个值间轮循 |
loop.depth |
当前循环在递归中的层级(从1开始) |
loop.depth0 |
当前循环在递归中的层级(从0开始) |
{% for row in rows %}
{% endfor %} |
4、渲染模板
使用Flask提供的渲染函数render_template()
from flask import Flask, render_template ... @app.route('/watchlist') def watchlist(): return render_template('watchlist.html', user=user, movies=movies) |
5、传入变量类型
传入Jinja2中的变量值可以是字符串、列表和字典,也可以是函数、类和类实例,这完全取决于你在视图函数传入的值。下面是一些示例:
这是列表my_list的第一个元素:{{ my_list[0] }} 这是元组my_tuple的第一个元素:{{ my_tuple[0] }} 这是字典my_dict的键为name的值:{{ my_dict['name'] }} 这是函数my_func的返回值:{{ my_func() }} 这是对象my_object调用某方法的返回值:{{ my_object.name() }} |
1、在模板中定义变量:使用set标签
{% set navigation = [('/', 'Home'), ('/about', 'About')] %} |
你也可以将一部分模板数据定义为变量,使用set和endset标签声明开始和结束:
{% set navigation %} {% endset %} |
2、内置上下文变量
Flask在模板上下文中提供了一些内置变量,可以在模板中直接使用。
config |
当前的配置对象 |
request |
当前的请求对象,在已激活的请求环境下可用 |
Session |
当前的会话对象,在已激活的请求环境下可用 |
g |
与请求绑定的全局变量,在已激活的请求环境下可用 |
3、自定义上下文
Flask提供了一个app.context_processor装饰器,当调用render_template()函数渲染任意一个模板时,所有使用app.context_processor装饰器注册的模板上下文处理函数(包括Flask内置的上下文处理函数)都会被执行,这些函数的返回值会被添加到模板中。
@app.context_processor def inject_foo(): foo = 'I am foo.' return dict(foo=foo) # 等同于return {'foo': foo} |
可以在模板中直接使用foo变量。
除了使用app.context_processor装饰器,也可以直接将其作为方法调用,传入模板上下文处理函数:
… def inject_foo(): foo = 'I am foo.' return dict(foo=foo) app.context_processor(inject_foo) |
使用lambda可以简化为:
app.context_processor(lambda: dict(foo='I am foo.')) |
4、全局对象
(1)内置全局对象
jinja2在模板中默认提供了一些全局函数,常用的三个函数:
range([start,] stop [,step]) |
与python 的range()用法相同 |
Lipsum(n=5,html=True,min=20,max=100) |
生成随机文本,可在测试时用来填充页面。默认生成5段HTML文本,每段包含20-100个单词。 |
dict(**items) |
和Python 的 dict()用法相同 |
除了jinja2内置的全局函数,flask也在模板中内置了两个全局函数
url_for() |
用于生成URL的函数 |
Get_flashed_message() |
用于获取flash消息的函数 |
(2)自定义全局函数
除了使用app.context_processor注册模板上下文处理函数来传入函数,我们也可以使用app.template_global装饰器直接将函数注册为模板全局函数。
@app.template_global() def bar(): return 'I am bar.' |
你可以直接使用app.add_template_global()方法注册自定义全局函数,传入函数对象和可选的自定义名称(name),比如app.add_template_global(your_global_function)。
5、过滤器
(1)基本用法
在Jinja2中,过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数,过滤器和变量用一个竖线(管道符号)隔开,需要参数的过滤器可以像函数一样使用括号传递。
{{ name|title }} |
这会将name变量的值标题化,相当于在Python里调用name.title() |
{{ movies|length }} |
用length获取movies列表的长度 |
过滤器可以叠加使用:
Hello, {{ name|default('陌生人')|title }}! |
(2)语块过滤:将过滤器作用于一部分模板数据,使用filter标签和endfilter标签声明开始和结束。下面使用upper过滤器将一段文字转换为大写:
{% filter upper %} This text becomes uppercase. {% endfilter %} |
(3)常用内置过滤器
A字符串操作:
{# 当变量未定义时,显示默认字符串,可以缩写为d #} {{ name | default('No name', true) }} {# 单词首字母大写 #} {{ 'hello' | capitalize }} {# 单词全小写 #} {{ 'XML' | lower }} {# 去除字符串前后的空白字符 #} {{ ' hello ' | trim }} {# 字符串反转,返回"olleh" #} {{ 'hello' | reverse }} {# 格式化输出,返回"Number is 2" #} {{ '%s is %d' | format("Number", 2) }} {# 关闭HTML自动转义在确保变量值安全的情况下,如果你想避免转义,将变量作为HTML解析,可以对变量使用safe过滤器:#} {{ 'name' | safe }} {{ santitized_text|safe }} {% autoescape false %} {# HTML转义,即使autoescape关了也转义,可以缩写为e #} {{ 'name' | escape }} {% endautoescape %} |
B 数值操作
{# 四舍五入取整,返回13.0 #} {{ 12.8888 | round }} {# 向下截取到小数点后2位,返回12.88 #} {{ 12.8888 | round(2, 'floor') }} {# 绝对值,返回12 #} {{ -12 | abs }} |
C 列表操作
{# 取第一个元素 #} {{ [1,2,3,4,5] | first }}
{# 取最后一个元素 #} {{ [1,2,3,4,5] | last }}
{# 返回列表长度,可以写为count #} {{ [1,2,3,4,5] | length }}
{# 列表求和 #} {{ [1,2,3,4,5] | sum }}
{# 列表排序,默认为升序 #} {{ [3,2,1,5,4] | sort }}
{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #} {{ [1,2,3,4,5] | join(' | ') }}
{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #} {{ ['tom','bob','ada'] | upper }} |
D 字典列表操作
{% set users=[{'name':'Tom','gender':'M','age':20}, {'name':'John','gender':'M','age':18}, {'name':'Mary','gender':'F','age':24}, {'name':'Bob','gender':'M','age':31}, {'name':'Lisa','gender':'F','age':19}] %}
{# 按指定字段排序,这里设reverse为true使其按降序排 #}
{% for user in users | sort(attribute='age', reverse=true) %}
{% endfor %}
{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
{% for group in users|groupby('gender') %}
{% endfor %}
{# 取字典中的某一项组成列表,再将其连接起来 #} {{ users | map(attribute='name') | join(', ') }} |
详细的查看官方文档
http://jinja.pocoo.org/docs/dev/templates/#builtin-filters
(4)Flask内置过滤器 tojson
Flask提供了一个内置过滤器”tojson”,它的作用是将变量输出为JSON字符串。这个在配合Javascript使用时非常有用。我们延用上节字典列表操作中定义的”users”变量.
var users = {{ users | tojson | safe }}; console.log(users[0].name); |
延用D 字典列表操作中定义的users变量。
(5)自定义过滤器
使用app.template_filter()装饰器可以注册自定义过滤器。
from flask import Markup @app.template_filter() def musical(s): return s + Markup(' ♫') |
模板中使用:
{{ name|musical }} |
也可以直接使用app.add_template_filter()方法注册自定义过滤器,传入函数对象和可选的自定义名称(name),比如app.add_template_filter(your_filter_function)。