flask基礎之請求鉤子(十二)
前言
什麼是請求鉤子?在客戶端和伺服器互動的過程中,有些準備工作或掃尾工作需要統一處理,為了讓每個檢視函式避免編寫重複功能的程式碼,flask提供了統一的介面可以新增這些處理函式,即請求鉤子。
請求鉤子的原理
先回顧一下flask對請求的處理流程:
接收請求--》建立請求上下文--》請求上下文入棧--》建立該請求的應用上下文--》應用上下文入棧--》處理邏輯--》請求上下文出棧--》應用上下文出棧
看了這個過程,flask放置請求鉤子的位置有:處理邏輯之前,處理邏輯之後,應用上下文出棧之前。
flask有五種常用請求鉤子:
before_first_request:在處理app第一個請求前執行。
before_request:在每次請求前執行。
after_request:如果處理邏輯沒有異常丟擲,在每次請求後執行。
teardown_request:在每次請求後執行,即使處理髮生了錯誤。
teardown_appcontext:在應用上下文從棧中彈出之前執行
定義請求鉤子
# before_request裝飾的方法會載入到app的before_request_funcs列表中,按載入的順序依次執行,不需要引數 @app.before_request def rest_test(): print('this is a test'+ '--2') pass # before_first_request裝飾的函式載入到before_first_request_funcs列表中,只不過在app第一次接收到請求後執行,其他時候不再執行 @app.before_first_request def app_first_request(): print('first_request' + '--1') # after_request裝飾的函式載入到after_request_funcs列表中,傳入的引數是response物件,可以對其進行攔截修改,必須返回一個response物件 @app.after_request def after_request(rsp): print(rsp) print('--3') return rsp # teardown_request裝飾的函式載入到teardown_request_funcs中,如果發生了異常則傳入error的物件,無異常引數為None,無返回值 @app.teardown_request def teardown_request(error): print(error) print('--4') # teardown_appcontext裝飾的函式載入到teardown_appcontext_funcs中,如果發生了異常則傳入error的物件,無異常引數為None,無返回值 @app.teardown_appcontext def teardown_appcontext(error): print('--5')
注意
在debug模式下,teardown_request和teardown_appcontext裝飾的函式不會執行;
after_request請求鉤子會自動傳入response物件作為引數,同時必須返回一個response物件;
before_request裝飾的函式不需要返回資料,如果返回了資料,那麼檢視函式不會再執行,而是直接返回結果。
藍圖的請求鉤子
藍圖存在的目的是為了在大型應用中對眾多的業務模組的api分層次管理,所以即使在主app下定義的路由規則,其預設是在None為名字的藍圖下面的,所以藍圖也有自己的請求鉤子,只在該藍圖下的api其作用。
from flask import Blueprint testblue = Blueprint('blue', __name__) # 藍圖也可以為主app新增請求鉤子,before_app_first_request裝飾會在app的before_first_request_funcs列表中,以None為鍵; @testblue.before_app_first_request def app_first_request(): print('first_request' + '--1') # 載入到app的before_request_funcs列表中,在None藍圖下,按載入的順序依次執行,不需要引數 @testblue.before_app_request def app_request(): pass # 載入到app的before_request_funcs列表中,在testblue藍圖下 @testblue.before_request def blue_before_request(): pass # 載入到after_request_funcs列表中,在testblue藍圖下 @testblue.after_request def after_request(rsp): return rsp # 載入到after_request_funcs列表中,在None藍圖下 @testblue.after_app_request def blue_after_app_request(rsp): return rsp #teardown_request裝飾的函式載入到app的teardown_request_funcs中,在testblue藍圖下 @testblue.teardown_request def teardown_request(error): print(error) print('--4') # 和teardown_request功能一樣,在None藍圖下 @testblue.teardown_app_request def blue_teardown_app_request(error): pass
注意
teardown_request裝飾的函式無論有沒有異常都執行,after_request裝飾的函式無異常才執行。
對於before_request、after_request、teardown_request請求鉤子,如果app存在相應的請求鉤子函式,則藍圖和app的請求鉤子函式都會執行,先執行app的鉤子函式,再執行藍圖的鉤子函式。
參考
- https://dormousehole.readthedocs.io/en/latest/