Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

时间:2024-12-06 14:05:26

1 测试器及其使用

  在模板中的 {{}} 可以书写测试器,格式如下

    {{ 变量 is 测试器名称  }}

  1.1 在python中导入 Jinja2 的模板

    from jinja2 import tests

      注意:其实这一步是不需要的,导入的目的是为了查看那些测试器的源代码

# -*- coding: utf-8 -*-
"""
jinja2.tests
~~~~~~~~~~~~ Jinja test functions. Used with the "is" operator. :copyright: (c) 2017 by the Jinja Team.
:license: BSD, see LICENSE for more details.
"""
import re
from collections import Mapping
from jinja2.runtime import Undefined
from jinja2._compat import text_type, string_types, integer_types
import decimal number_re = re.compile(r'^-?\d+(\.\d+)?$')
regex_type = type(number_re) test_callable = callable def test_odd(value):
"""Return true if the variable is odd."""
return value % 2 == 1 def test_even(value):
"""Return true if the variable is even."""
return value % 2 == 0 def test_divisibleby(value, num):
"""Check if a variable is divisible by a number."""
return value % num == 0 def test_defined(value):
"""Return true if the variable is defined: .. sourcecode:: jinja {% if variable is defined %}
value of variable: {{ variable }}
{% else %}
variable is not defined
{% endif %} See the :func:`default` filter for a simple way to set undefined
variables.
"""
return not isinstance(value, Undefined) def test_undefined(value):
"""Like :func:`defined` but the other way round."""
return isinstance(value, Undefined) def test_none(value):
"""Return true if the variable is none."""
return value is None def test_lower(value):
"""Return true if the variable is lowercased."""
return text_type(value).islower() def test_upper(value):
"""Return true if the variable is uppercased."""
return text_type(value).isupper() def test_string(value):
"""Return true if the object is a string."""
return isinstance(value, string_types) def test_mapping(value):
"""Return true if the object is a mapping (dict etc.). .. versionadded:: 2.6
"""
return isinstance(value, Mapping) def test_number(value):
"""Return true if the variable is a number."""
return isinstance(value, integer_types + (float, complex, decimal.Decimal)) def test_sequence(value):
"""Return true if the variable is a sequence. Sequences are variables
that are iterable.
"""
try:
len(value)
value.__getitem__
except:
return False
return True def test_equalto(value, other):
"""Check if an object has the same value as another object: .. sourcecode:: jinja {% if foo.expression is equalto 42 %}
the foo attribute evaluates to the constant 42
{% endif %} This appears to be a useless test as it does exactly the same as the
``==`` operator, but it can be useful when used together with the
`selectattr` function: .. sourcecode:: jinja {{ users|selectattr("email", "equalto", "foo@bar.invalid") }} .. versionadded:: 2.8
"""
return value == other def test_sameas(value, other):
"""Check if an object points to the same memory address than another
object: .. sourcecode:: jinja {% if foo.attribute is sameas false %}
the foo attribute really is the `False` singleton
{% endif %}
"""
return value is other def test_iterable(value):
"""Check if it's possible to iterate over an object."""
try:
iter(value)
except TypeError:
return False
return True def test_escaped(value):
"""Check if the value is escaped."""
return hasattr(value, '__html__') def test_greaterthan(value, other):
"""Check if value is greater than other."""
return value > other def test_lessthan(value, other):
"""Check if value is less than other."""
return value < other TESTS = {
'odd': test_odd,
'even': test_even,
'divisibleby': test_divisibleby,
'defined': test_defined,
'undefined': test_undefined,
'none': test_none,
'lower': test_lower,
'upper': test_upper,
'string': test_string,
'mapping': test_mapping,
'number': test_number,
'sequence': test_sequence,
'iterable': test_iterable,
'callable': test_callable,
'sameas': test_sameas,
'equalto': test_equalto,
'escaped': test_escaped,
'greaterthan': test_greaterthan,
'lessthan': test_lessthan
}

所有测试器的源代码

    Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

  1.2 直接在模板的 {{}} 中书写书写对应的测试器即可    

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo01</title>
</head>
<body>
<h2>测试器</h2>
<hr /> <h3>测试odd/even</h3>
<p>{{ 3 is odd }}</p>
<p>{{ 4 is even }}</p>
<p>
{% if (var01 is even) %}
var01是偶数
{% else %}
var01不是偶数
{% endif %}
</p>
<hr /> <h3>测试test_divisibleby</h3>
<p>
{{ 4 is divisibleby 2 }}
<br />
{% if (var02 is divisibleby 2) %}
var02能被2整除
{% endif %}
</p>
<hr /> <h3>测试test_defined/test_undefined</h3>
<p>
{{ var03 is defined }}
<br />
{% if var03 is defined %}
var03已经被定义
{% endif %}
<br />
{{ var04 is undefined }}
<br />
{% if var04 is undefined %}
var04没有被定义
{% endif %}
</p>
<hr /> <h3>测试test_none</h3>
<p>
{{ var05 is none }}
<br />
{% if var05 is none %}
var05的值是None
{% endif %}
</p>
<hr /> <h3>测试test_lower/test_upper</h3>
<p>
{{ var06 is lower }}
<br />
{% if var06 is lower %}
var06的值全是小写
{% endif %}
<br />
{{ var07 is upper }}
<br />
{% if var07 is upper %}
var07的值全是大写
{% endif %}
</p>
<hr /> <h3>测试test_string</h3>
<p>
{{ var08 is string }}
<br />
{% if var08 is string %}
var08的值是一个字符串
{% else %}
var08的值不是一个字符串
{% endif %}
</p>
<hr /> <h3>测试test_mapping</h3>
<p>
{{ var09 is mapping }}
<br />
</p>
<hr /> <h3>测试test_number</h3>
<p>
{{ var10 is number }}
<br />
</p>
<hr /> <h3>测试test_sequence</h3>
<p>
{{ var11 is sequence }}
<br />
</p>
<hr /> <h3>测试test_equalto</h3>
<p>
{{ var12 is equalto 'zeus' }}
<br />
{% if var12 is equalto 'zeus' %}
var12的值是zeus
{% endif %}
</p>
<hr /> <h3>测试test_sameas</h3>
<p>
{{ var13 is sameas false }}
</p>
<hr /> <h3>测试test_iterable</h3>
<p>
{{ var14 is iterable }}
</p>
<hr /> <h3>测试test_escaped</h3>
<p>
{{ var15 is escaped }}
</p>
<hr /> <h3>测试test_greaterthan</h3>
<p>
{{ 3 is greaterthan 2 }}
</p>
<hr /> <h3>测试test_lessthan</h3>
<p>
{{ 3 is lessthan 4 }}
</p> {# <h3>notes</h3>#}
<p>
{# {{ loop.length }} 循环总次数#}
{# {{ loop.index }} 当前次数,下标从1开始#}
{# {{ loop.index0 }} 当前次数,下标从0开始#}
{# {{ loop.reindex }} 当前次数反向#}
{# {{ loop.cycle('a','b','c') }} 循环自动返回元素 #}
{# {{ loop.first }} 首次迭代时返回true#}
{# {{ loop.last }} 首次迭代是返回false#}
</p>
</body>
</html>

html模板代码

from flask import Blueprint
from flask import render_template
# from jinja2 import tests bp_test = Blueprint('test', __name__) @bp_test.route('/test/')
def test():
content = {
'name':'warrior',
'var01': 3,
'var02': 4,
'var03': 5,
'var05': None,
'var06': 'warrior',
'var07': 'WARRIOR',
'var08': 234,
'var09': {
'name':"fury"
},
'var10': 14,
'var11': 1324,
'var12': 'zeus',
'var13': False,
'var14': 'warrior',
'var15': 'good'
}
resp = render_template('demo01.html', **content)
return resp

蓝图代码

from flask import Flask
from flask import render_template
from jinja2 import tests from demo01 import bp_test app = Flask(__name__) app.register_blueprint(bp_test) # @app.route('/')
# def hello_world():
# resp = render_template('index.html', info='warrior')
# return resp print(app.url_map) if __name__ == '__main__':
app.run(debug=True)

python代码

2 控制语句

  在控制语句上的表达式不用写在 {{ }} 中;但是在控制语句中的表达式必须写在 {{ }} 中

  Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

  2.1 IF控制语句

{% if var01 < 5 %}
条件1成立
{% elif var01 < 10 %}
条件2成立
{% else %}
条件1和2都不成立
{% endif %}

  2.2 FOR控制语句

% for foo in ['warrior', 'fury', 'zeus'] %}
{{ foo }} <br />
{% endfor %}

  注意:在python代码中 for 和 else 搭配是循环完毕后执行else后面的语句;但是在Jinja2模板中却只有0次迭代(即:不进行迭代)时执行else后面的语句

{% for foo in var02 if foo == 'mother' %}
{{ foo }} <br />
{% else %}
在var02中没有满足条件的元素
{% endfor %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Controller</title>
</head>
<body>
<h2>测试流程控制语句</h2>
<hr /> <h4>测试IF语句</h4>
<p>
{% if var01 < 5 %}
条件1成立
{% elif var01 < 10 %}
条件2成立
{% else %}
条件1和2都不成立
{% endif %}
</p>
<hr /> <h4>测试FOR语句</h4>
<p>
{% for foo in ['warrior', 'fury', 'zeus'] %}
{{ foo }} <br />
{% endfor %}
<hr />
{% for foo in var02 if foo == 'mother' %}
{{ foo }} <br />
{% else %}
在var02中没有满足条件的元素
{% endfor %}
</p>
</body>
</html>

html模板

from flask import Blueprint
from flask import render_template bp_controller = Blueprint('controller', __name__) @bp_controller.route('/controller/')
def control():
content = {
'var01': 199,
'var02': ['good', 'boy']
}
resp = render_template('controller.html', **content)
return resp;

蓝图代码

from flask import Flask
from flask import render_template
from jinja2 import tests # from testor import bp_test
from controller import bp_controller app = Flask(__name__) # app.register_blueprint(bp_test)
app.register_blueprint(bp_controller) # @app.route('/')
# def hello_world():
# resp = render_template('index.html', info='warrior')
# return resp print(app.url_map) if __name__ == '__main__':
app.run(debug=True)

python代码

    2.2.1 FOR循环的补充

    <p>
{# {{ loop.length }} 循环总次数#}
{# {{ loop.index }} 当前次数,下标从1开始#}
{# {{ loop.index0 }} 当前次数,下标从0开始#}
{# {{ loop.reindex }} 当前次数反向#}
{# {{ loop.cycle('a','b','c') }} 循环自动返回元素 #}
{# {{ loop.first }} 首次迭代时返回true#}
{# {{ loop.last }} 首次迭代是返回false#}
</p>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试模板</title>
</head>
<body>
<h2>这里是测试模板的内容</h2>
{% for foo in range(10) %}
{# <li>当前次数(从1开始):{{ loop.index }} --> 内容:{{ foo }}</li>#}
<li>当前次数(从0开始):{{ loop.index0 }} --> 内容:{{ foo }}</li>
{# <h2>{{ loop.length }}</h2>#}
{# {{ loop.first }} #}
{# {{ loop.last }}#}
{% endfor %} </body>
</html>

html模板

from flask import Blueprint
from flask import render_template bp_test = Blueprint('test', __name__, url_prefix='/test') @bp_test.route('/test/')
def test():
return render_template('test.html')

蓝图代码

from flask import Flask
from flask import url_for # from bp_include import bp_test
# from bp_extends import bp_extends
from bp_test import bp_test app = Flask(__name__) # app.register_blueprint(bp_test)
# app.register_blueprint(bp_extends)
app.register_blueprint(bp_test) @app.route('/')
def hello_world():
return 'Hello World!' print(app.url_map) if __name__ == '__main__':
app.run(debug=True)

python代码

3 赋值

  3.1 变量赋值

    {% set 变量名 =  值 %}

<h4>变量赋值</h4>
<p>
{% set student = 'warrior' %}
学生姓名:{{ student }}
<hr />
{% set students = ['fury','zeus','warrior'] %}
<p>
{% for student in students %}
{{ student }} <br />
{% endfor %} </p>
</p>

  3.2 块赋值

<h4>块赋值</h4>
<p>
{% set xxx %}
<li>Hello Boy</li>
<li>Hello World</li>
{% endset %}
{{ xxx }}
</p>

4 作用域

  IF语句没有作用域,FOR语句有作用域;其它的{% %}通常产生作用域

  4.1 测试IF语句没有作用域

    Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

  4.2 设置IF语句的作用域

    利用块级作用域来设置IF语句的作用域

    Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

  4.3 测试FOR语句有作用域

    Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

  

5 块级作用域

{% with %}
块级作用域中的内容
{% endwith %}

  5.1 不要在with上这样写

      Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

      会出现以下的报错信息

        Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

          原因:造成了变量污染

  5.2 解决办法

    Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

 流程控制:
if
测试
测试器(一个函数) from jinja2 import tests
is 后面跟的必须是个测试器 for
和else搭配 不是表示正常迭代完
而是表示 0次迭代,或全部被 if 过滤 {% for i in xxx if ... %} 赋值:
变量赋值
块赋值 好处:
1.中间变量
2.方便测试 作用域:
if不产生作用域
for 产生作用域
其他的{% %}通常产生作用域 构造局部作用域
with
不要在 with 写这种 : {% with name=[1,2], xx=name[1] %} 应该要
{% with name=[1,2]
{% set xx=name[1] %}
{% endwith %} 好处: 防止变量污染 注意! 所有的语句标签,都必须要 {% xx %} {% endxx %} 小练习:
1. 把所有的测试器,都测试一遍
2. 把上次的按个导航条,改进以下,如果render_template('xx.html', user=user)
那么就通过if判断,如果有这个user那么就显示用域名
如果没有user,或者user是个None就 显示登陆注册
logo左浮动 右边写 login-group,右浮动
3. 传一个老列表,在模板里面用for迭代渲染li标签

思维笔记

6 模拟登录

  要求:如果用户名和密码都正确就显示  欢迎 XXX,否则就显示  登录和注册

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<style>
#head {
background-color: skyblue;
border: 1px solid red;
}
li {
list-style-type: none;
}
.group-item {
float: left;
padding:0 10px;
}
.login-item {
float: right;
padding:0 10px;
}
.clear {
clear: both;
}
a {
text-decoration: none;
}
li:hover {
background-color: blue
}
a:hover {
color: yellow;
}
</style>
</head>
<body>
<div id="head">
<ul>
<li class="group-item"><a href="#">首页</a></li>
<li class="group-item"><a href="#">python</a></li>
<li class="group-item"><a href="#">java</a></li>
<li class="group-item"><a href="#">angular</a></li>
{% if (name is equalto "warrior") and (pwd is equalto "123321") %}
<li class="login-item"><span>欢迎&nbsp;{{ name }}</span></li>
{% else %}
<li class="login-item"><a href="#">登录</a></li>
<li class="login-item"><a href="#">注册</a></li>
{% endif %}
<div class="clear"></div>
</ul>
</div>
</body>
</html>

htmo模板代码

from flask import Blueprint
from flask import render_template bp_login = Blueprint("login", __name__) @bp_login.route('/login/')
def toLogin():
content = {
'name': 'warrior',
'pwd': '123321'
}
resp = render_template('login.html', **content)
return resp

蓝图代码

 from flask import Flask
from flask import render_template
from jinja2 import tests # from testor import bp_test
# from controller import bp_controller
from login import bp_login app = Flask(__name__) # app.register_blueprint(bp_test)
# app.register_blueprint(bp_controller)
app.register_blueprint(bp_login) # @app.route('/')
# def hello_world():
# resp = render_template('index.html', info='warrior')
# return resp print(app.url_map) if __name__ == '__main__':
app.run(debug=True)

python代码

Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域

Flask07 Jinja2模板测试器、控制语句IF/FOR、变量/块 赋值、作用域、块级作用域