介绍

在Django中有中间件这个类来做一些视图执行前、执行中、执行后的一些额外业务处理,那么在Flask则是采用请求钩子的方式来处理。

请求钩子

在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:在请求开始时,建立数据库连接;在请求结束时,指定数据的交互格式。为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。

请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:

  • before_first_request:在处理第一个请求前运行。
  • before_request:在每次请求前运行。
  • after_request:如果没有未处理的异常抛出,在每次请求后运行。
  • teardown_request:在每次请求后运行,即使有未处理的异常抛出。

示例代码

from flask import Flask, request, url_for


app = Flask(__name__)


@app.route("/index")
def index():
print("index 被执行")
a = 1 / 0 # 执行出现异常
return "index page"

@app.route("/hello")
def hello():
print("hello 被执行")
return "hello page"

@app.before_first_request
def handle_before_first_request():
"""在第一次请求处理之前先被执行"""
print("handle_before_first_request 被执行")

@app.before_request
def handle_before_request():
"""在每次请求之前都被执行"""
print("handle_before_request 被执行")

@app.after_request
def handle_after_request(response):
"""在每次请求(视图函数处理)之后都被执行, 前提是视图函数没有出现异常"""
print("handle_after_request 被执行")
return response

@app.teardown_request
def handle_teardown_request(response):
"""在每次请求 (视图函数处理)之后都被执行, 无论视图函数是否出现异常,都被执行, 工作在非调试模式时 debug=False"""
path = request.path
if path == url_for("index"):
print("在请求钩子中判断请求的视图逻辑: index")
elif path == url_for("hello"):
print("在请求钩子中判断请求的视图逻辑: hello")
print("handle_teardown_request 被执行")
return response

if __name__ == '__main__':
app.run()
  • 执行index 如下:
16. Flask 请求钩子_Flask教程

查看后台打印的信息,如下:

16. Flask 请求钩子_Flask_02

可以看到尽管出现了异常,teardown_request的钩子也会照常执行。

  • 执行hello 如下:
16. Flask 请求钩子_Flask教程_0316. Flask 请求钩子_Flask_04