1. 模板全局变量
1.1 current_user
使用过Flask-Login的同学应该都知道,在他的扩展中有一个属性current_user用来保存当前登录用户的相关信息,比如登录状态、登录信息等。而且这个current_user属性除了能在我们后端的python代码中使用外,还可以在任何模板中进行使用,如下面的代码片段
在python后端代码中使用
def test():
...
# 在python后端代码中使用
if current_user.is_authenticated:
li = LoveInfo(user=current_user.username, user_ip=remote_ip)
else:
li = LoveInfo(user='Anonymous', user_ip=remote_ip)
在html模板文件中使用
{% if not current_user.is_authenticated %}
<ul class="navbar-nav f-17">
<li class="nav-item"><a class="nav-link nav-text" href="/auth/login/">登录</a></li>
<li class="nav-item"><a class="nav-link nav-text" href="/auth/register/">注册</a></li>
</ul>
{% else %}
...
{% endif %}
在python代码中还比较好理解,当我们需要使用的时候,直接通过import导入即可,但是为什么current_user能够在任意模板文件中使用呢?我们可以通过分析Flask-Login的源码来理解为何可以在任意模板文件中使用。一般的,当我们使用Flask-Login的时候都是通过实例化LoginManager示例,然后通过instance.init_app(app, *args)来注册实例。我们可以进入LoginManager源码,init_app()函数代码如下
def init_app(self, app, add_context_processor=True):
'''
Configures an application. This registers an `after_request` call, and
attaches this `LoginManager` to it as `app.login_manager`.
:param app: The :class:`flask.Flask` object to configure.
:type app: :class:`flask.Flask`
:param add_context_processor: Whether to add a context processor to
the app that adds a `current_user` variable to the template.
Defaults to ``True``.
:type add_context_processor: bool
'''
app.login_manager = self
app.after_request(self._update_remember_cookie)
if add_context_processor:
app.context_processor(_user_context_processor)
可以看到add_context_processor变量的注释
Whether to add a context processor to the app that adds a `current_user` variable to the template. Defaults to ``True``.
翻译为中文的大概意思就是,是否向应用程序添加上下文处理器,以将 current_user 变量添加到模板,默认为True。继续看if语句里面的代码,_user_context_processor是一个方法,其代码如下
def _user_context_processor():
return dict(current_user=_get_user())
可以看到函数就是返回了一个字典对象,可以发现字典的键就是current_user。为什么current_user可以使用在任意模板中,就是通过app.context_processor Api添加了一个应用程序上下文函数来实现,在Flask的文档中描述如下图所示,翻译过来的意思就是注册一个模板上下文处理器函数。
1.2 使用
context_processor的使用方法有两种,如下代码所示,分别使用装饰器的方式定义模板全局变量以及方法,已函数的形式定义模板全局变量。
from flask import Flask
import datetime
app = Flask(__name__)
# use decorator
@app.context_processor()
def cur_day():
return datetime.date.today()
# context function
@app.context_processor()
def get_uuid():
import uuid
def _uuid():
return uuid.uuid3()
return dict(uuid=_uuid)
def current_time():
return dict(current_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
# use context_processor function
app.context_processor(current_time)
2.自定义过滤器
Flask已经内置了很多过滤器,比如truncate、length等,除了内置的过滤器之外,我们还可以自定义Jinja2模板的过滤器。在Flask中有两种方法自定义过滤器,代码如下
@app.template_filter('reverse')
def reverse_filter(s):
return s[::-1]
def reverse_filter(s):
return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter
第一种方法是使用app.template_filter()装饰器来实现,装饰器中的参数,就是后续可以在Jinja2模板文件中使用的过滤器名称;
第二种方法是通过app.jinja_env.filters将过滤器函数存入字典中,字典的键就是Jinja2模板文件中使用的过滤器名称;
示例代码链接: