什麼是請求鉤子?在客戶端和服務器交互的過程當中,有些準備工做或掃尾工做須要統一處理,爲了讓每一個視圖函數避免編寫重複功能的代碼,flask提供了統一的接口能夠添加這些處理函數,即請求鉤子。python
先回顧一下flask對請求的處理流程:flask
接收請求--》建立請求上下文--》請求上下文入棧--》建立該請求的應用上下文--》應用上下文入棧--》處理邏輯--》請求上下文出棧--》應用上下文出棧api
看了這個過程,flask放置請求鉤子的位置有:處理邏輯以前,處理邏輯以後,應用上下文出棧以前。服務器
flask有五種經常使用請求鉤子:app
before_first_request:在處理app第一個請求前運行。函數
before_request:在每次請求前運行。this
after_request:若是處理邏輯沒有異常拋出,在每次請求後運行。debug
teardown_request:在每次請求後運行,即便處理髮生了錯誤。rest
teardown_appcontext:在應用上下文從棧中彈出以前運行code
# 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的鉤子函數,再執行藍圖的鉤子函數。