flask默认使用的模板引擎是jinja2,它是一个功能齐全的python模板引擎,除了设置变量,还允许我们添加if判断,执行for循环,调用函数等。以各种方式控制模板的输出。
对应jinja2来说,模板可以是任何格式的纯文本文件,比如HTML、XML、CSV等。
1.1模板变量
变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。
语法如下:
{{ var }}
你可以使用点( . )来访问变量的属性,作为替代,也可以使用所谓的“下标”语 法( [])。下面的几行效果是一样的:
{{foo.bar }}
{{ foo['bar'] }}
如果变量或属性不存在,会返回一个未定义值。
def book_list(request):
books = BookInfo.objects.all()
context = {'books': books}
return render(request, 'book_list.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书列表</title>
</head>
<body>
{{ books }}
<br>
{{ books.0 }}
<br>
{{ books.0.author }}
</body>
</html>
1.2模板语句
1)for循环:
和其它语句一样,需要在for循环的结尾使用{% endfor %} 标签声明for语句的结束。
{% for row in rows %}
<li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
{% endfor %}
loop.index
loop.index0
loop.reindex
loop.reindex0
loop.first
loop.last
loop.length
loop.cycle
loop.depth
loop.depth0
loop.previtem
loop.nextitem
在for循环内,jinja2提供了多个特殊变量,
变量名****作用loop.index当前迭代数,从1开始计数loop.index()当前迭代数,从0开始计数loop.revindex当前反向迭代数,从1开始计数loop.revindex()当前反向迭代数,从0开始计数loop.first如果是第一个元素则为Trueloop.last如果是最后一个元素则为Trueloop.previtem上一个迭代的条目loop.nextitem下一个迭代的条目loop.length序列中元素的数量
- else,iteration为空,执行else
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no users found</em></li>
{% endfor %}
</ul>
- for if
{% for user in users if not user.hidden %}
<li>{{ user.username|e }}</li>
{% endfor %}
- 递归 for
<ul class="sitemap">
{%- for item in sitemap recursive %}
<li><a href="{{ item.href|e }}">{{ item.title }}</a>
{%- if item.children -%}
<ul class="submenu">{{ loop(item.children) }}</ul>
{%- endif %}</li>
{%- endfor %}
</ul>
loop的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ user.username }}'s watchlist</title>
</head>
<body>
<a href="{{ url_for('hi') }}">← Return</a>
<h2>{{ user.username}}</h2>
{% if user.bio %}
<i>{{ user.bio }}</i>
{% else %}
<i>This user has not provided a bio.</i>
{% endif %}
{# 以下是电影清单(这是注释) #}
<h5>{{ user.username }}'s watchlist ({{ movies|length }}):</h5>
<ul>
{% for movie in movies %}
<li>loop.index:{{ loop.index }} loop.first:{{ loop.first }}
loop.last:{{ loop.last }} - {{ movie.name }} - {{ movie.year }}</li>
{% endfor %}
</ul>
</body>
</html>
浏览器访问:http://127.0.0.1:5000/watchlist
2)if条件:
{% if ... %}
{% elif ... %}
{% else %}
{% endif %}
比较运算符如下:
==
!=
<
>
<=
>=
布尔运算符如下:
and
or
not
3)注释
{{ #...#}}
1.3结构标签
block
{% block xxx %}
pass
{% endblock %}
extends
{% extends 'xxx' %}
续承后保留块中的内容
{{ super() }}
include
{% include 'xxx' %}
包含,将其他HTML包含进来,体现的是由零到一的概念
marco
{% marco hello(name) %}
{{ name }}
{% endmarco %}
宏定义,可以在模块中定义函数,在其他地方调用
宏定义可以导入
{% from 'xx' import xxx %}
jinja2通过了多种控制结构来控制模板的输出,其中for和if是最常用的2种。jinja2里,语句使用{undefined{%...%}}标识。需要注意的是,在语句结束的地方,必须添加结束标签,如:
{% if user.bio %}
<i>{{ user.bio }}</i>
{% else %}
<i>This user has not provided a bio.</i>
{% endif %}
在这个if语句中,如果user.bio已经定义,就渲染{% if user.bio %}和{% else %}之间的内容,否则就渲染{% else %}和{% endif %}之间的内容。末尾的{% endif %}用来表示if语句的结束,不能省略。
1.4空白处理
您也可以手动去除模板中的空白。 如果加减号 符号 (
-
) 到块的开头或结尾(例如 For 标签),a 注释或变量表达式,之前或之后的空格 该块将被删除:
{% for item in seq -%}
{{ item }}
{%- endfor %}
不得在标记和减号之间添加空格。
**有效 **:
**{%- if foo -%}...{% endif %}**
**无效 **:
**{% - if foo - %}...{% endif %}**
2.1过滤器
过滤器:本质上就是一个python语言定义的一个方法,但是在模板语言中不能直接调用python的方法,只能通过过滤器的方式来调用。
即python中定义方法,仍后将方法加入到过滤器列表中,加入后就可以在模板语言中进行调用。 而且模板语言支持链式调用,比如:{{"hello world" | reverse | upper }}
模板语言过滤器调用格式:{{variable | filter_func_name(*args)}}
没有参数时可以将参数括号省略如:{{variable | filter_func_name}}
链式调用:{{variable | filter_func_name1 | filter_func_name2}}
字符串操作
safe:禁用转义
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把变量值的首字母转成大写,其余字母转小写
<p>{{ 'hello' | capitalize }}</p>
lower:把值转成小写
<p>{{ 'HELLO' | lower }}</p>
upper:把值转成大写
<p>{{ 'hello' | upper }}</p>
title:把值中的每个单词的首字母都转成大写
<p>{{ 'hello' | title }}</p>
reverse:字符串反转
<p>{{ 'olleh' | reverse }}</p>
format:格式化输出
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
truncate: 字符串截断
<p>{{ 'hello every one' | truncate(9)}}</p>
列表操作:
first:取第一个元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
last:取最后一个元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
length:获取列表长度
<p>{{ [1,2,3,4,5,6] | length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
语句块过滤
{% filter upper %}
#一大堆文字#
{% endfilter %}
自定义过滤器:
自定义过滤器有两种实现方式:
一种是通过Flask应用对象的 add_template_filter 方法
- 通过调用应用程序实例的 add_template_filter 方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:
def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li)
# 将新列表进行返转
temp_li.reverse()
return temp_li
app.add_template_filter(do_listreverse,'lireverse')
- 用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器名称。
@app.template_filter('lireverse')def do_listreverse(li): # 通过原列表创建一个新列表 temp_li = list(li) # 将新列表进行返转 temp_li.reverse() return temp_li
在 html 中使用该自定义过滤器<br/> my_array 原内容:{{ my_array }}<br/> my_array 反转:{{ my_array | lireverse }}
运行结果
my_array 原内容:[3, 4, 2, 1, 7, 9]
my_array 反转:[9, 7, 1, 2, 4, 3]
3.1包含
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。
功能是将另一个模板整个加载到当前模板中,并直接渲染。
- include的使用
{% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上 ignore missing 关键字。如果包含的模板文件不存在,会忽略这条include语句。
- include 的使用加上关键字ignore missing
{% include 'hello.html' ignore missing %}
3.2 宏
对宏(macro)的理解:
把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串。
为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复使用。
定义宏:
{% macro input(name,value='',type='text') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" class="form-control">
{% endmacro %}
调用宏:
{{ input('name' value='zs')}}
上面对于宏的调用,相当于输出
<input type="text" name="name"
value="zs" class="form-control">
把宏单独抽取出来,封装成html文件,其它模板中导入使用,文件名可以自定义macro.html
{% macro input(label="", type="text", name="", value="") %}
<label>{{ label }}</label>
<input type="{{ type }}" name="{{ name }}"
value="{{ value }}">
{% endmacro %}
参考文档:Jinja模板语法官方文档
jinja2语法_王培军的博客-CSDN博客_jinja2语法
版权归原作者 菜菜zhao 所有, 如有侵权,请联系我们删除。