内置过滤器
jinja2
中过滤器其实是一个函数,通过管道运算符|
实现操作。语法:
{{ name | length }}
1.内置过滤器列表
abs(value)
返回绝对值 attr(obj, name)
返回对象的属性,类似 foo['bar']
capitalize(s)
返回首字母大写的值 center(value, width=80)
居中显示 default(value,default_value=u,boolean=Flase)
如果当前变量没有值,则会使用参数中的值来代替 escape(vale)
或者:e
转义字符,会将 ,&
等等,转为html中对应的值,jinja2
默认开启了转义.first(value)
返回一个序列的第一个元素 last(value)
返回一个序列的最后一个元素 format(value,*args,**kwargs)
格式化字符串 length(value)
返回一个序列或者字典的长度 join(value, d='u')
将一个序列用d这个参数的值拼接成字符串 safe(value)
如果开启了全局转义.那么safe过滤器会将变量关掉转义 int(value)
将值转换为int类型 float(value)
将值转换为float类型 upper(value)
将字符串转换为大写 lower(value)
将字符串转换为小写 replace(value, old, new)
将old替换为new的字符串 truncate(value,length=253,killwords=False)
截取length长度的字符串 striptags(value)
删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格 reverse(value)
反转字符串 trim(value)
截取字符串前面和后面的空白字符 string(value)
将变量转换成字符串 wordcount(s)
计算一个长字符串中单词的个数
2.实例
#!/usr/bin/env python# coding = utf-8"""演示 jinja2模板中的内置过滤器"""from flask import Flaskfrom flask import url_for, render_templateapp = Flask(__name__)@app.route('/')def index(): exam = { 'A' : -5 } return render_template('index.html', info = exam )if __name__=='__main__': app.run(debug=True, host='192.168.0.101', port=8080)
jinja2
返回后端信息:{{ info }}
返回绝对值:{{ info.A | abs }}
3.其他参考
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
{{ name | default('no name', true) }}
{# 首字母大写 #}
{{ 'hello' | capitalize }}
{# 单词全部小写 #}
{{ 'XML' | lower }}
{# 去除字符串前后的空白字符 #}
{{ ' hello ' | trim }}
{# 字符串反转 #}
{{ 'hello' | reverse }}
{# 格式化输出 #}
{{ "%s is %d" | format('number', 2) }}
{# 关闭HTML自动转义 #}
{{ 'name' | safe }}
{# HTML转义,即使autoescape关了也转义,可以缩写为e #} {% autoescape false %}
{{ 'name' | escape }}
{% endautoescape %}
{# 四舍五入取整 #} {{ 12.9999 | round }} {# 向下截取到小数点后两位,返回12.88 #} {{ 12.8888 | round(2, 'floor') }} {# 取绝对值 #} {{ -12 | abs }}
{# 取第一个元素 #}
{{ [1,2,3,4,5] | first }}
{# 取最后一个元素 #}
{{ [1,2,3,4,5] | last }}
{# 返回列表长度 #}
{{ [1,2,3,4,5] | length }}
{# 列表求和 #}
{{ [1,2,3,4,5] | sum }}
{# 列表排序,默认是升序 #}
{{ [1,2,3,4,5] | sort }}
{# 合并为字符串,返回 "1 | 2 | 3 | 4 | 5" #}
{{ [1,2,3,4,5] | join('|') }}
{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
{{ ['tom','bob','ada'] | upper }}
{% 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) %} {{ user.name }}, {{ user.age }} {% endfor %} {# 列表分组,每组是一个子列表,组名就是分组项的值 #} {% for group in users|groupby('gender') %} {{ group.grouper }} {% for user in group.list %} {{ user.name }} {% endfor %} {% endfor %} {# 取字典中的某一项组成列表,再将其连接起来 #}
{{ users | map(attribute='name') | join(', ') }}
4.default
过滤器的场景
典型应用场景就是个性签名
from flask import Flask,render_template,url_forapp = Flask(__name__)@app.route('/')def index():return "Hello World"@app.route('/signature/')def my_signature():information = { 'signature1': '', 'signature2': [], 'signature3': None, 'signature4':'天行健,君子以自强不息.'}return render_template('signature.html', **information)if __name__=='__main__':app.run(debug=True)
HTML
文件signature
签名: {{ signature1 | default('此人很懒,没有任何签名!') }}
签名: {{ signature2 | default('此人很懒,没有任何签名!') }}
签名: {{ signature3 | default('此人很懒,没有任何签名!') }}
签名: {{ signature4 | default('此人很懒,没有任何签名!') }}
--------------------------------------------------------------------
签名: {{ signature1 | default('此人很懒,没有任何签名!',boolean=True) }}
签名: {{ signature2 | default('此人很懒,没有任何签名!',boolean=True) }}
签名: {{ signature3 | default('此人很懒,没有任何签名!',boolean=True) }}
签名: {{ signature4 | default('此人很懒,没有任何签名!',boolean=True) }}
当不设置
boolean=True
时,就会判断传入的变量的布尔值,如果是变量的值是None
,空列表,空字符串,则不会显示`defalut
中定义的值,因为在python中,None
空字符串,空列表,空字典的布尔值是False
.设置
boolean
=True,如果变量有内容输出内容,否则输出默认值.
5.设置模板实时加载
在设置
app.run(debug=True)
,Flask
会自动检测python
文件,自动更新,不需要去重启服务器程序,但是更改模板文件时,有时候不会实时的去加载模板文件,为了解决这个问题,可以在Flask
中配置app.config['TEMPLATE_AUTO_RELOAD'] = True
6.自定义过滤器
jinja2
中,除了默认的过滤器,还可以自定义过滤器。比如根据不同的级别用户的欢迎信息。from flask import Flaskfrom flask import url_for,render_template,gapp = Flask(__name__)# 在配置文件中跟新模板实时跟新和debugapp.config.update({'DEBUG': True, 'TEMPLATE_AUTO_RELOAD':True})# 自定义过滤器def handle_user(value):if value == 'Jack': return 'Permission Deny'elif value == 'admin': return 'Welcome'# 注册自定义过滤器app.add_template_filter(handle_user, 'handle_user')@app.route('//')def index(user): info = { 'User' : { 'Jack' : 'general_user', 'admin' : 'administrator' } } g.user = user return render_template('index.html', uname = g.user, **info )if __name__ == '__main__': app.run()
{# index.html #}
{{ uname | handle_user }}
以上需要注意的是
g
,这时一个全局变量。访问结果:
注意: 可以使用
app.add_template_filter()
来注册模板,也可以使用更优雅的方式:装饰器@app.add_template_filter('handle_user')def handle_user(value): if value == 'Jack': return 'Permission Deny' elif value == 'admin': return 'Welcome'
7.时间过滤器实例
from flask import Flask, render_templatefrom datetime import datetime# 初始化app = Flask(__name__)# 开启模板/py 文件自动加载app.config['TEMPLATES_AUTO_RELOAD'] = Trueapp.config['Debug'] = True@app.route('/')def index(): return render_template('index.html')@app.route('/login//')def login(name): return render_template('login.html', user=name)# 登录数据率user_information = { 'admin': { 'id': 1, 'user_name': 'admin', 'administrator': True, 'last_login_time': datetime(2019, 10, 19, 9, 55, 17, 864217) }, 'Jack': { 'id': 2, 'user_name': 'Jack', 'administrator': False, 'last_login_time': datetime(2019, 10, 19, 9, 50, 10, 864217) }, 'Bob': { 'id': 3, 'user_name': 'Bob', 'administrator': False, 'last_login_time': datetime(2019, 10, 19, 7, 55, 17, 864217) }, 'Harry': { 'id': 4, 'user_name': 'Harry', 'administrator': False, 'last_login_time': datetime(2019, 10, 10, 9, 55, 17, 864217) }}now = datetime(2019, 10, 19, 9, 55, 19, 864217)# 定义处理时间的filter@app.template_filter('handle_time')def handle_time(name): def handle_time_charge(time1, time2): my_time = (time1 - time2).total_seconds() if my_time < 60: return '刚刚' elif 60 <= my_time < 60 * 60: my_time = int(my_time / 60) return '{}分钟前'.format(my_time) elif 60 * 60 <= my_time < 60 * 60 * 60: my_time = int(my_time / (60 * 60)) return '{}小时前'.format(my_time) else: return time1 for key, value in user_information.items(): if key == name: mytime = handle_time_charge(now, value['last_login_time']) if value['administrator']: return 'welcome administrator {} {}登录'.format(value['user_name'], mytime) else: return 'welcome {} {}登录'.format(value['user_name'], mytime)if __name__ == '__main__': app.run(debug=True)