自定义过滤器
过滤器的本质是函数。当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:
重要:自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。
需求:添加列表反转的过滤器
方式一
通过调用应用程序实例的 add_template_filter 方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:
def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li) # 将新列表进行返转
temp_li.reverse() return temp_li
app.add_template_filter(do_listreverse,'lireverse')
方式二
用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器名称。
@app.template_filter('lireverse')def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li) # 将新列表进行返转
temp_li.reverse() return temp_li<br/> my_array 原内容:{{ my_array }}<br/> my_array 反转:{{ my_array | lireverse }}my_array 原内容:[3, 4, 2, 1, 7, 9]
my_array 反转:[9, 7, 1, 2, 4, 3]
==================================================================================================
==================================================================================================
控制代码块
控制代码块主要包含两个:
- if/else if /else / endif
- for / endfor
if语句
Jinja2 语法中的if语句跟 Python 中的 if 语句相似,后面的布尔值或返回布尔值的表达式将决定代码中的哪个流程会被执行:
{%if user.is_logged_in() %}
<a href='/logout'>Logout</a>
{% else %}
<a href='/login'>Login</a>
{% endif %}过滤器可以被用在 if 语句中:
{% if comments | length > 0 %}
There are {{ comments | length }} comments
{% else %}
There are no comments
{% endif %}循环
{% for post in posts %}
<div>
<h2>{{ post.title }}</h2>
<p>{{ post.text | safe }}</p>
</div>
{% endfor %}{% for post in posts if post.text %}
<div>
<h2>{{ post.title }}</h2>
<p>{{ post.text | safe }}</p>
</div>
{% endfor %}| 变量 | 描述 |
|---|
| loop.index | 当前循环迭代的次数(从 1 开始) |
| loop.index0 | 当前循环迭代的次数(从 0 开始) |
| loop.revindex | 到循环结束需要迭代的次数(从 1 开始) |
| loop.revindex0 | 到循环结束需要迭代的次数(从 0 开始) |
| loop.first | 如果是第一次迭代,为 True 。 |
| loop.last | 如果是最后一次迭代,为 True 。 |
| loop.length | 序列中的项目数。 |
| loop.cycle | 在一串序列间期取值的辅助函数。见下面示例程序。 |
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}1, Post title2, Second Post
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}odd Post Title
even Second Post
==================================================================================================
==================================================================================================
模板代码复用
在模板中,可能会遇到以下情况:
像遇到这种情况,可以使用 JinJa2 模板中的 继承来进行实现
模板继承
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
{% block top %} {% endblock %}相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。
子模板使用 extends 指令声明这个模板继承自哪个模板
父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()
父模板
{% block top %}
顶部菜单
{% endblock top %}
{% block content %}
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}子模板
{% extends 'base.html' %}
{% block content %}
需要填充的内容
{% endblock content %}模板继承使用时注意点:
不支持多继承
为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。
不能在一个模板文件中定义多个相同名字的block标签。
当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。
==================================================================================================
==================================================================================================
模板中特有的变量和函数
你可以在自己的模板中访问一些 Flask 默认内置的函数和对象
config
你可以从模板中直接访问Flask当前的config对象:
{{config.SQLALCHEMY_DATABASE_URI}}
sqlite:///database.dbrequest
就是flask中代表当前请求的request对象:
{{request.url}}
http://127.0.0.1g变量
在视图函数中设置g变量的 name 属性的值,然后在模板中直接可以取出
{{ g.name }}get_flashed_messages()
这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉:
{%for message in get_flashed_messages()%}
{{message}}
{%endfor%}