Flask的四个钩子

168 阅读2分钟

Flask 提供了四种常用的钩子(Hook),也就是装饰器,用于在处理 HTTP 请求过程中插入自定义代码。这四种钩子分别是:

  1. before_first_request:注册一个函数,在处理第一个请求之前运行。这通常用于创建数据库链接、初始化数据等操作。

  2. before_request:注册一个函数,在每次请求之前运行。这可以用于打开数据库连接、加载用户会话信息、检查用户的 IP 地址等。如果这个函数返回了一个响应,那么 Flask 将不会调用视图函数,直接将这个响应返回给客户端。

  3. after_request:在每次请求处理完毕后运行,但是它是在视图函数处理完之后才会运行。这个函数可以对响应对象进行修改,如设置 HTTP Headers,然后返回这个修改过的响应对象。如果视图函数或者 before_request 内部发生了错误,导致异常被抛出,则这个函数不会被执行。

  4. teardown_request:注册一个函数,无论请求是否成功,都在每次请求结束后运行。这个函数必须接受一个参数,即要么是错误原因,要么是 None(成功处理请求)。这个函数内部要处理错误存在/不存在两种情况。这个钩子和 after_request 钩子的区别在于,即使视图函数内部发生了错误,导致异常抛出,这个钩子函数仍然会被执行。所以这个钩子常常被用来释放资源,比如关闭数据库连接。

以上这四个钩子都可以在一个 Flask 实例上面注册多个。另外需要注意的是,注册 after_requestteardown_request 时,最好保证它们的顺序,因为 Flask 执行这两个钩子的顺序和它们的注册顺序是相反的。

from flask import Flask
app = Flask(__name__)

@app.before_first_request
def before_first_request_func():
    print("This is executed BEFORE the first request")

@app.before_request
def before_request_func():
    print("This is executed BEFORE each request")

@app.after_request
def after_request_func(response):
    print("This is executed AFTER each request")
    return response

@app.teardown_request
def teardown_request_func(error=None):
    if error:
        print("This is executed when error occurs in the view function")
        print('Error:', error)
    else:
        print("This is executed when no error occurs in the view function, i.e., normal case")

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()

在这段代码中,我们定义了四个钩子函数,它们会在 Flask 处理请求的不同阶段被调用。我们在每个函数里面加入了打印语句,这样就可以观察到它们被执行的顺序和条件。