首页域名资讯 正文

Flask的Jinja2模板引擎 — 测试器(4th)

2024-11-23 5 0条评论

Jinja2中的测试器Test和过滤器非常相似,区别是测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,你需要使用”is”关键字来进行测试。测试器一般都是跟着if控制语句一起使用的。下面我们就来深入了解下这个测试器。

测试器使用

再次取回第一篇的例子,我们在模板中对变量name作如下判断:

1 2 3 { % if name is lower % }    < h2 > “{{ name }}” are all lower case . < / h2 > { % endif % }

当name变量中的字母都是小写时,这段文字就会显示。这就是测试器,在if语句中,变量或表达式的后面加上is关键字,再加上测试器名称,就可以对该变量或表达式作测试,并根据其测试结果的真或假,来决定是否进入if语句块。测试器也可以有参数,用括号括起。当其只有一个参数时,可以省去括号。

1 2 3 { % if 6 is divisibleby 3 % }    < h2 > “divisibleby” test pass < / h2 > { % endif % }

上例中,测试器”divisibleby”可以判断其所接收的变量是否可以被其参数整除。因为它只有一个参数,我们就可以用空格来分隔测试器和其参数。上面的调用同”divisibleby(3)”效果一致。测试器也可以配合not关键字一起使用:

1 2 3 { % if 6 is not divisibleby ( 4 ) % }    < h2 > “not divisibleby” test pass < / h2 > { % endif % }

显然测试器本质上也是一个函数,它的第一个参数就是待测试的变量,在模板中使用时可以省略去。如果它有第二个参数,模板中就必须传进去。测试器函数返回的必须是一个布尔值,这样才可以用来给if语句作判断。

内置测试器 Builtin Tests

同过滤器一样,Jinja2模板引擎提供了丰富的内置测试器。这里介绍几个常用的。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 { # 检查变量是否被定义,也可以用undefined检查是否未被定义 #} { % if name is defined % }      < p > Name is : { { name } } < / p > { % endif % } { # 检查是否所有字符都是大写 #} { % if name is upper % }    < h2 > “{{ name }}” are all upper case . < / h2 > { % endif % } { # 检查变量是否为空 #} { % if name is none % }    < h2 > Variable is none . < / h2 > { % endif % } { # 检查变量是否为字符串,也可以用number检查是否为数值 #} { % if name is string % }    < h2 > { { name } } is a string . < / h2 > { % endif % } { # 检查数值是否是偶数,也可以用odd检查是否为奇数 #} { % if 2 is even % }    < h2 > Variable is an even number . < / h2 > { % endif % } { # 检查变量是否可被迭代循环,也可以用sequence检查是否是序列 #} { % if [ 1 , 2 , 3 ] is iterable % }    < h2 > Variable is iterable . < / h2 > { % endif % } { # 检查变量是否是字典 #} { % if { ‘name’ : ‘test’ } is mapping % }    < h2 > Variable is dict . < / h2 > { % endif % }

自定义测试器

如果内置测试器不满足需求,我们就来自己写一个。写法很类似于过滤器,先在Flask应用代码中定义测试器函数,然后通过”add_template_test”将其添加为模板测试器:

1 2 3 4 import re def has_number ( str ) :      return re . match ( r ‘.*\d+’ , str ) app . add_template_test ( has_number , ‘contain_number’ )

我们定义了一个”has_number”函数,用正则来判断输入参数是否包含数字。然后调用”app.add_template_test”方法,第一个参数是测试器函数,第二个是测试器名称。之后,我们就可以在模板中使用”contain_number”测试器了:

1 2 3 { % if name is contain_number % }    < h2 > “{{ name }}” contains number . < / h2 > { % endif % }

同过滤器一样,Flask提供了添加测试器的装饰器”template_test”。下面的代码就添加了一个判断字符串是否以某一子串结尾的测试器。装饰器的参数定义了该测试器的名称”end_with”:

1 2 3 @ app . template_test ( ‘end_with’ ) def end_with ( str , suffix ) :      return str . lower ( ) . endswith ( suffix . lower ( ) )

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

1 2 3 { % if name is end _with “me” % }    < h2 > “{{ name }}” ends with “me” . < / h2 > { % endif % }

Flask添加测试器的方法是封装了对Jinja2环境变量的操作。上述添加”end_with”测试器的方法,等同于下面的代码。

1 app . jinja_env . tests [ ‘end_with’ ] = end_with

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

完整代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from flask import Flask , render_template import re app = Flask ( __name__ ) @ app . route ( ‘/hello’ ) @ app . route ( ‘/hello/<name>’ ) def hello ( name = None ) :      return    render_template ( ‘hello-4.html’ , name = name ) def has_number ( str ) :      return    re . match ( r ‘.*\d+’ , str ) app . add_template_test ( has_number , ‘contain_number’ ) @ app . template_test ( ‘end_with’ ) def end_with ( str , suffix ) :      return str . lower ( ) . endswith ( suffix . lower ( ) ) if __name__ == ‘__main__’ :      app . run ( debug = True )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 < ! doctype html > < title > Hello Sample < / title > { % if name % }    < h1 > Hello { { name } } ! < / h1 > { % else % }    < h1 > Hello World ! < / h1 > { % endif % } { % if 6 is divisibleby 3 % }    < h2 > “divisibleby” test pass < / h2 > { % endif % } { % if 6 is not divisibleby ( 4 ) % }    < h2 > “not divisibleby” test pass < / h2 > { % endif % } { # 检查变量是否被定义,也可以用undefined检查是否未被定义 #} { % if name is defined % }      < p > Name is : { { name } } < / p > { % if name is lower % }    < h2 > “{{ name }}” are all lower case . < / h2 > { % endif % } { # 检查是否所有字符都是大写 #} { % if name is upper % }    < h2 > “{{ name }}” are all upper case . < / h2 > { % endif % } { # 检查变量是否为空 #} { % if name is none % }    < h2 > Variable is none . < / h2 > { % endif % } { # 检查变量是否为字符串,也可以用number检查是否为数值 #} { % if name is string % }    < h2 > { { name } } is a string . < / h2 > { % endif % } { # 检查数值是否是偶数,也可以用odd检查是否为奇数 #} { % if 2 is even % }    < h2 > Variable is an even number . < / h2 > { % endif % } { # 检查变量是否可被迭代循环,也可以用sequence检查是否是序列 #} { % if [ 1 , 2 , 3 ] is iterable % }    < h2 > Variable is iterable . < / h2 > { % endif % } { # 检查变量是否是字典 #} { % if { ‘name’ : ‘test’ } is mapping % }    < h2 > Variable is dict . < / h2 > { % endif % } { % if name is contain_number % }    < h2 > “{{ name }}” contains number . < / h2 > { % endif % } { % if name is end _with “me” % }    < h2 > “{{ name }}” ends with “me” . < / h2 > { % endif % } { % endif % }

文章转载来自:trustauth.cn

文章版权及转载声明

本文作者:亿网 网址:https://www.edns.com/ask/post/163342.html 发布于 2024-11-23
文章转载或复制请以超链接形式并注明出处。