Jinja2 测试器
Jinja2中的测试器和过滤器非常相似,区别是测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,需要用is
关键字来进行测试。测试器一般都会跟着if
控制语句一起使用。
-
• 内置测试器
{% if variable is escaped%}
value of variable: {{ escaped }}
{% else %}
variable is not escaped
{% endif %}
以上判断variable
这个变量是否已经被转义了,Jinja
中内置了许多的测试器,看以下列表:
测试器 | 说明 |
callable(object) |
检查是否可调用。 |
defined(value) |
检查是否已经被定义了。 |
divisibleby(value, num) |
检查是否可以被数字整除。 |
equalto(value, other) |
检查一个对象是否与另一个对象具有相同的值。 |
escaped(value) |
检查是否已经被转义了。 |
even(value) |
检查是否是偶数。 |
iterable(value) |
检查是否可以迭代对象。 |
lower(value) |
检查是否全是小写。 |
mapping(value) |
如果对象是映射(dict 等),则返回 true。 |
none(value) |
如果变量为无,则返回真。 |
number(object) |
检查是否是一个数字。 |
odd(object) |
检查是否是奇数。 |
sameas(value, other) |
检查一个对象是否与另一个对象指向相同的内存地址。 |
sequence(value) |
检查是否是一个序列。 |
string(value) |
检查是否是一个字符串。 |
undefined(value) |
类似于defined()。 |
upper(value) |
检查是否全是大写。 |
参考示例:
{# 检查变量是否被定义,也可以用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
将其添加为模版测试器:
import re
from flask import FLask
app = Flask(__name__)
def has_number(str):
return re.match(r'.*d+', str)
app.add_template_test(has_number, 'contain_number')
if __name__ == '__main__':
app.run(debug=True)
定义了一个has_number
函数,用正则来判断输入参数是否包含数字。然后调用app.add_template_test
方法,第一个参数是测试器函数,第二个是测试器名称,可以在模版中contain_number
测试器。
{% if name is contain_number %}
<h2>"{{name}}" contain_number</h2>
{% endif %}
同过滤器一样,Flask提供了添加测试器的装饰器template_test
。下面的代码就添加了一个判断字符串是否已某一个串结尾的测试器。装饰器的参数定义了该测试器的名称end_with
:
@app.template_test('end_with')
def end_with(str, suffix):
return str.lower().endswith(suffix.lower())
在模版中可以这样使用:
{% if name is end_with "me" %}
<h2>"{{ name }}" ends with "me".</h2>
{% endif %}
Flask添加测试器的方法是封装了对Jinji2环境变量的操作,上述添加end_with
测试的方法,等同于下面方式。
app.jinja_env.tests['end_with'] = end_with
在Flask
应用中,不建议直接访问Jinja2的环境变量。如果离开Flask
环境直接使用Jinja2的话,就可以通过Jinja2.Environment
来获取环境变量,并添加测试器。
Jinja2 宏和import
-
• 宏Jinja2模版中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
{% endmacro %}
上述的代码定义了一个宏,宏的定义要加macro
,宏定义结束要加endmacro
标志,抽取出了一个inpurt
标签,指定了一些默认参数,那么以后创建inpurt
标签的时候,可以通过它快速的创建。
<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>
-
• import在真实的开发过程中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。
import
语句的用法跟python
中的import
类似,可以直接import...as...
,也可以form...import...
或者from...import...as...
。 -
• 参考示例froms.html
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{% endmacro %}
{% macro textarea(name, value='', rows=10, cols=40) %}
<textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
}}">{{ value|e }}</textarea>
{% endmacro %}
-
1.
import...as...
形式
{% import 'forms.html' as forms %}
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>Password</dt>
<dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>
-
1.
from...import...as.../from...import...
形式
{% from 'forms.html' import input as input_field, textarea %}
<dl>
<dt>Username</dt>
<dd>{{ input_field('username') }}</dd>
<dt>Password</dt>
<dd>{{ input_field('password', type='password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>
另外需要注意的是,导入模板并不会把当前上下文中的变量添加到被导入的模板中,如果你想要导入一个需要访问当前上下文变量的宏,有两种可能的方法:
-
• 显式地传入请求或请求对象的属性作为宏的参数。
-
• 与上下文一起(with context)导入宏。与上下文中一起(with context)导入的方式如下:
{% from '_helpers.html' import my_macro with context %}
Jinja2 include和set语句
-
• include语句
include
语句可以把一个模版引入到另一个模版中,类似于把一个模版的代码copy到另外一个模版的指定位置。
{% include 'header.html' %}
主体内容
{% include 'footer.html' %}
-
• 赋值(set)语句在模版中添加变量
{% set name="Jinja2" %}
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %} <!-- 赋值为列表和元组 -->
赋值语句创建的变量在其之后都是有效的,如果不想让一个变量污染全局环境,可以使用with
语句来创建一个内部的作用域,将set
语句放在其中,这样创建的变量只在with
代码块中才有效。
{% with %}
{% set foo = 42 %}
{{ foo }}
{% endwith %}
也可以在with
的后面直接添加变量,比如以上的写法可以修改成这样:
{% with foo = 42 %}
{{ foo }}
{% endwith %}
这两种方式都是等价的,一旦超出with
代码块,就不能再使用foo
这个变量了。
来源:网络
欢迎关注我的公众号“壹葉筆記”,技术文章第一时间推送。
原文始发于微信公众号(壹葉筆記):【Flask】扩展:Jinja2 模板(二)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/36106.html