1. 程式人生 > >flask基礎之請求鉤子(十二)

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/