flask 钩子函数原理图
钩子函数是指在执行函数和目标函数之间挂载的函数, 框架开发者给调用方提供一个全局的入口, 函数位置和内容自定义
2.常用的钩子函数
2.1• before_first_request 处理第一次请求之前执行
服务器被第一次访问执行的钩子函数
注意:钩子函数是装饰器调用的,也就是后面没有括号的,千万注意这个后面没有括号。
@app.before_first_request
def first_request():
print("Hello World")
如果是挂在蓝图上则要使用
.before_app_first_request 来实现一样的功能
@user_bp.before_app_first_request
def first_request():
print("Hello World")
2.2 在每次请求之前执行. 通常使用这个钩子函数预处理一些变量
@app.before_request #注册在APP上
def before():
pass
@user_bp.before_app_request #注册在蓝图上
def before():
pass
这个钩子最常用,用来做登录校验,下面是登录校验钩子的例子
小技巧:这里能拿到每次请求的URL路径的相对路径:requser.path
可用这个路径判断一下是到哪个页面,可以选择是否拦截这个页面,比如未登录用户,那他只能在登录和注册两个页面活动,其他页面都要被拦截跳转到登录页面。
如果执行print(request.path) 命令,那么发挥的是类似下面的url地址
/user #比如这样的
/user/register #或者是这样的
另外,还有一个关于g的知识点,因为这个全局钩子装饰器执行在前那么我们在钩子中做了用户认证了可以获取到用户登录ID,那么如何把这个ID内容可靠的传送到本次目标视图里呢?
这里就需要全局对象g
帮忙,这个g类似是一个空的类你可以把任意名称的属性附着在它身上并在本次请求中传送到目标视图。用法:
from flask import g
g.user='good' # 随便赋值个属性名和值就可以在本次的视图函数中接收了
假如下面是目标视图
@user.route('\user')
def user_1():
print(g.user) #这样就能获取了
下面这个视图是如何构建登录安全网的例子。
@app.before_request #这个注册在APP上了
def before_request():
name = session.get("name")
if name:#拿到数据,下面处理用户权限
g.name=name # 有数据就附着上给视图传过去
else:#没有登录,重定向到登录页面
if request.path == '/user/register':
pass
else:
return redirect('/login')
2.3 .after_request 是在视图执行完毕返回response的时候执行,所以,这个钩子需要在函数括号里边传入返回的response对象。
这个玩意比较少用,适用场景主要是能在这里给response添加头以及处理response,啥的
@app.after_request #注册在APP上
def after(response):
pass
@user_bp.after_app_request #注册在蓝图上
def after2(response):
pass
2.4 .teardown_request
这个在after后面执行。
@app.teardown_request #注册在APP上
def after():
pass
@user_bp.teardown_app_request #注册在蓝图上
def after2():
pass
2.5 .teardown_appcontex
• teardown_appcontext 当APP上下文被移除之后执行的函数, 可以进行数据库的提交或者回滚
@app.teardown_appcontext
def teardown(exc=None):
if exc is None:
db.session.commit()
else:
db.session.rollback()
db.session.remove()
2.6
• template_filter, 增加模板过滤器
@app.template_filter
def upper_filter(s):
return s.upper()
• context_processor 上下文处理器, 返回的字典可以在全部模板中使用
@app.context_processor()
def context():
# 必须返回一个字典
# hasattr(obj, attr) 判断obj是否有attr属性, 注意此时的attr应该是字符串
if hasattr(g, "user"):
return {"current_username": "DaYe"}
else:
# 注意: 必须返回一个字典
return {}
• errorhander, 在发生一些异常时, 比如404错误, 就会自动调用对应的钩子函数
1.发生请求错误时, 框架会自动调用相对钩子函数, 并向钩子函数传入error参数
2.如果钩子函数没有定义error参数, 就会报服务器错误
3.开发者可以通过flask.abort方法手动抛出异常, 比如发现输入的参数错误可以使用abort(404)来解决
@app.errorhander(404)
def page_not_found(error):
return render_template("error400.html"), 404
@app.errorhander(500)
def server_error(error):
return render_template("error505.html"), 500