一、过滤器
模板中的过滤器
模板中的过滤器可以对来自响应中数据进行处理,过滤器有以下几种使用方式:
- 使用管道符
|
,可以进行链式调用,也可以通过()
进行传参 - 使用
filter
标签
在 app.py 中新增视图函数 filter。
@app.route('/filter') def filter(): name = 'Thor' heros = {'stark', 'clint', 'loki'} return render_template('filter.html', name=name, heros=heros) 复制代码
在 templates 文件夹下新建 filter.html 页面。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Filter</title> </head> <body> <h2>使用管道符 |</h2> <p>{{ name|upper }}</p> <p>{{ name|lower }}</p> <p>{{ heros|length }}</p> <p>{{ heros|join('-') }}</p> <p>{{ heros|join('-')|length }}</p> </body> </html> 复制代码
重新启动应用,浏览器访问 /filter,页面数据经过管道符 |
的过滤,显示结果如下:
修改 filter.html,改为通过标签方式使用过滤器,内容如下:
<h2>使用filter标签</h2> {% filter upper %} <p>{{ name }}</p> {% endfilter %} {% filter lower %} <p>{{ name }}</p> {% endfilter %} {# 注意空格#} {% filter join('-') %}{{ name }}{% endfilter %} 复制代码
保存代码后浏览器再次访问 /filter 路径,页面显示结果如下:
内置的过滤器函数生效。
常用的内置过滤器
Jinja2 模板引擎中内置了一些常用的过滤器,如:
{{ value | abs}}
:获取 value 的绝对值{{ value | default('默认值') }}
或{{ value | d('默认值') }}
:默认值显示{{ value | escape }}
或{{ value | e }}
:HTML 转义{{ value | safe }}
:富文本内容转义{{ value | reverse }}
:反转
在 app.py 中的 filter 函数中增加一些变量,用于测试 abs 和 default 过滤器。
@app.route('/filter') def filter(): name = 'Thor' heros = {'stark', 'clint', 'loki'} abs_value = -1 d_value = 1 d_none_value = None return render_template('filter.html', name=name, heros=heros, abs_value = abs_value, d_value = d_value, d_none_value = d_none_value) 复制代码
在 filter.html 页面中使用这些变量,只需在 body 标签中添加如下内容:
<h2>内置过滤器</h2> <h3>获取绝对值过滤器</h3> <p>{{ abs_value | abs }}</p> <h3>默认值过滤器</h3> <p>{{ d_value | default(0) }}</p> <p>{{ d_value_2 | default(0) }}</p> <p>{{ d_none_value | default(0) }}</p> <h4> defalut 过滤器默认 None 值生效</h4> <p>{{ d_none_value | default(0, True) }}</p> 复制代码
保存代码,浏览器访问 /filter,页面显示结果如下:
可以看出 default 过滤器只会对没有定义的变量起作用,当变量的值为 None 时无效。
如果先要使用默认值来取代 None 的值只需要在 default 函数中再增加一个 Bool 参数且值为 True 即可,在 filter.html 中的 body 标签中增加如下内容:
<h4> defalut 过滤器默认 None 值生效</h4> <p>{{ d_none_value | default(0, True) }}</p> 复制代码
保存代码,浏览器再次访问 /filter,页面显示结果如下:
None 值已经被默认值取代。
Jinja2 模板中使用 autoescape
标签设置全局是否自动转义,如果要局部设置需要使用 escape
过滤器。
在 filter 函数中将一段 html 代码保存到变量中,并存放在上下文中。
@app.route('/filter') def filter(): # 其余代码保持不变 html_code = "<h4>这是一段 HTML 代码</h4>" return render_template('filter.html', name=name, heros=heros, abs_value = abs_value, d_value = d_value, d_none_value = d_none_value, html_code = html_code) 复制代码
在 filter.html 中使用 escape 过滤器渲染上下文中的变量。
<h2>内置过滤器</h2> <h3>escape 过滤器</h3> {% autoescape false %} <p> {{ html_code | e}} </p> <p> {{ html_code }} </p> {% endautoescape %} 复制代码
默认开启了 autoescape
,因此转义 html 时加不加 escape
过滤器结果都是会被自动转义。
更多内置过滤器的使用可查看 Jinja2 官网中列出的过滤器清单。
自定义过滤器
如果模板中提供的过滤器都无法满足需求,那么就需要自定义过滤器,比如个人信息脱敏等。
自定义过滤器有两种方式,以自定义一个隐藏个人真实姓名的过滤器 name_masking 为例。
第一种方式,使用装饰器注册自定义过滤器
在 app.py 中新增函数 name_masking_filter,使用装饰器 @app.template_filter
将该函数注册为一个过滤器,装饰器后的括号中指定过滤器的名字,既可以在模板中使用的名字。
@app.template_filter('name_masking') def name_masking_filter(name): return name[0] + '**' 复制代码
在 filter.html 页面中使用该过滤器,在 body 标签中增加如下内容:
<h2>自定义过滤器使用</h2> <p>{{ '特朗普' | name_masking }}</p> 复制代码
保存代码,浏览器访问 /filter。
名字已经被替换为 **
第二种方式,使用函数注册自定义过滤器
将上面使用装饰器注册过滤器的代码注释掉,只需要将装饰器注释即可,通过 Flask 对象 app 调用 jinja_env 函数来注册自定义的过滤器。
def name_masking_filter(name) return return name[0] + '**' # 注册自定义过滤器 app.jinja_env.filters['name_masking'] = name_masking_filter 复制代码
保存代码,浏览器访问 /filter。
过滤器生效,名字已经被替换为 **。