Flask 学习系列---Jinjia2使用过滤器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask 学习系列---Jinjia2使用过滤器相关的知识,希望对你有一定的参考价值。

再Jinjia2中过滤器是一种转变变量输出内容的技术。··过滤器通过管道符号“|与变量链接,并且可以通过圆括号传递参数” 。举例说明:

{{my_variable|default(\'my_variable is not defined\')}}

 my_variable 为变量,default为过滤器,my_variable is not defined是过滤器的参数。default过滤器的含义是:判断被转换的变量是否被定义过,如果没有被定义,则用字符串参数替换被转换的变量。

下面列出几个常用的过滤器

字符串操作:

	
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
<p>{{ name | default(\'No name\', true) }}</p>
 
{# 单词首字母大写 #}
<p>{{ \'hello\' | capitalize }}</p>
 
{# 单词全小写 #}
<p>{{ \'XML\' | lower }}</p>
 
{# 去除字符串前后的空白字符 #}
<p>{{ \'  hello  \' | trim }}</p>
 
{# 字符串反转,返回"olleh" #}
<p>{{ \'hello\' | reverse }}</p>
 
{# 格式化输出,返回"Number is 2" #}
<p>{{ \'%s is %d\' | format("Number", 2) }}</p>
 
{# 关闭html自动转义 #}
<p>{{ \'<em>name</em>\' | safe }}</p>
 
{% autoescape false %}
{# HTML转义,即使autoescape关了也转义,可以缩写为e #}
<p>{{ \'<em>name</em>\' | escape }}</p>
{% endautoescape %}

 数值操作

{# 四舍五入取整,返回13.0 #}
<p>{{ 12.8888 | round }}</p>
 
{# 向下截取到小数点后2位,返回12.88 #}
<p>{{ 12.8888 | round(2, \'floor\') }}</p>
 
{# 绝对值,返回12 #}
<p>{{ -12 | abs }}</p>

 列表操作

{# 取第一个元素 #}
<p>{{ [1,2,3,4,5] | first }}</p>
 
{# 取最后一个元素 #}
<p>{{ [1,2,3,4,5] | last }}</p>
 
{# 返回列表长度,可以写为count #}
<p>{{ [1,2,3,4,5] | length }}</p>
 
{# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p>
 
{# 列表排序,默认为升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p>
 
{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(\' | \') }}</p>
 
{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
<p>{{ [\'tom\',\'bob\',\'ada\'] | upper }}</p>

 字典列表操作

{% 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使其按降序排 #}
<ul>
{% for user in users | sort(attribute=\'age\', reverse=true) %}
     <li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>
 
{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
<ul>
{% for group in users|groupby(\'gender\') %}
    <li>{{ group.grouper }}<ul>
    {% for user in group.list %}
        <li>{{ user.name }}</li>
    {% endfor %}</ul></li>
{% endfor %}
</ul>
 
{# 取字典中的某一项组成列表,再将其连接起来 #}
<p>{{ users | map(attribute=\'name\') | join(\', \') }}</p>

 自定义过滤器

内置的过滤器不满足需求怎么办?自己写呗。过滤器说白了就是一个函数嘛,我们马上就来写一个。回到Flask应用代码中:

我们定义了一个”double_step_filter”函数,返回输入列表的偶数位元素(第0位,第2位,..)。怎么把它加到模板中当过滤器用呢?Flask应用对象提供了”add_template_filter”方法来帮我们实现。我们加入下面的代码:

函数的第一个参数是过滤器函数,第二个参数是过滤器名称。然后,我们就可以愉快地在模板中使用这个叫”double_step”的过滤器了:

Flask还提供了添加过滤器的装饰器”template_filter”,使用起来更简单。下面的代码就添加了一个取子列表的过滤器。装饰器的参数定义了该过滤器的名称”sub”。

我们在模板中可以这样使用它:

Flask添加过滤器的方法实际上是封装了对Jinja2环境变量的操作。上述添加”sub”过滤器的方法,等同于下面的代码。

我们在Flask应用中,不建议直接访问Jinja2的环境变量。如果离开Flask环境直接使用Jinja2的话,就可以通过”jinja2.Environment”来获取环境变量,并添加过滤器。

 

完整代码如下:

from flask import Flask,render_template
 
app = Flask(__name__)
 
@app.route(\'/glq\')
@app.route(\'/glq/<name>\')
def hello(name=None):
    return render_template(\'glq.html\', name=name)
 
########## Add Filter ##########
def double_step_filter(l):
    return l[::2]
app.add_template_filter(double_step_filter, \'double_step\')
 
@app.template_filter(\'sub\')
def sub(l, start, end):
    return l[start:end]
 
#app.jinja_env.filters[\'sub\'] = sub
 
if __name__ == \'__main__\':
    app.run(host=\'0.0.0.0\', debug=True)

 

html端代码为:

 

<!DOCTYPE html>
<title>Hello Sample</title>

{% if name %}
  <h1>Hello {{ name | upper | truncate(3, True) }}!</h1>
{% else %}
  <h1>Hello World!</h1>
{% endif %}


{# 字符串操作 #}
{# 当变量未定义时,显示默认字符串 #}
<p>{{ name | default(\'No name\', true) }}</p>

{# 单词首字母大写 #}
<p>{{ \'hello\' | capitalize }}</p>

{# 单词全小写 #}
<p>{{ \'XML\' | lower }}</p>

{# 去除字符串前后的空白字符 #}
<p>{{ \'  hello  \' | trim }}</p>

{# 字符串反转,返回"olleh" #}
<p>{{ \'hello\' | reverse }}</p>

{# 格式化输出,返回"Number is 2" #}
<p>{{ \'%s is %d\' | format("Number", 2) }}</p>

{# 关闭HTML自动转义 #}
<p>{{ \'<em>name</em>\' | safe }}</p>

{% autoescape false %}
{# HTML转义,即使autoescape关了也转义 #}
<p>{{ \'<em>name</em>\' | escape }}</p>
{% endautoescape %}


{# 数值操作 #}
{# 四舍五入取整,返回13.0 #}
<p>{{ 12.8888 | round }}</p>

{# 向下截取到小数点后2位,返回12.88 #}
<p>{{ 12.8888 | round(2, \'floor\') }}</p>

{# 绝对值,返回12 #}
<p>{{ -12 | abs }}</p>

{# 列表操作 #}
{# 取第一个元素 #}
<p>{{ [1,2,3,4,5] | first }}</p>

{# 取最后一个元素 #}
<p>{{ [1,2,3,4,5] | last }}</p>

{# 返回列表长度 #}
<p>{{ [1,2,3,4,5] | length }}</p>

{# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p>

{# 列表排序,默认为升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p>

{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(\' | \') }}</p>

{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
<p>{{ [\'tom\',\'bob\',\'ada\'] | upper }}</p>

{# 字典列表操作 #}
{% 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使其按降序排 #}
<ul>
{% for user in users | sort(attribute=\'age\', reverse=true) %}
     <li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>

{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
<ul>
{% for group in users|groupby(\'gender\') %}
    <li>{{ group.grouper }}<ul>
    {% for user in group.list %}
        <li>{{ user.name }}</li>
    {% endfor %}</ul></li>
{% endfor %}
</ul>

{# 取字典中的某一项组成列表,再将其连接起来 #}
<p>{{ users | map(attribute=\'name\') | join(\', \') }}</p>

{# tojson #}
<script type="text/javascript">
var users = {{ users | tojson | safe }};
console.log(users[0].name);
</script>

{% filter upper %}
    This is a Flask Jinja2 introduction.
{% endfilter %}

{# 自定义过滤器 #}
{# 返回[1,3,5] #}
<p>{{ [1,2,3,4,5] | double_step }}</p>

{# 返回[2,3,4] #}
<p>{{ [1,2,3,4,5] | sub(1,4) }}</p>

运行效果图:

 

以上是关于Flask 学习系列---Jinjia2使用过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Flask 学习系列---Jinjia2 模板继承

flask jinjia2过滤器的使用

[Flask]过滤器-控制字符串展示长度

jinjia2

flask中jinjia2模板使用详解2

flask中jinjia2模板引擎使用详解2