Flask 延遲請求回調(diào)

2021-08-11 10:34 更新

Flask 的設(shè)計原則中有一條是響應(yīng)對象被創(chuàng)建并在一條可能的回調(diào)鏈中傳遞,而在 這條回調(diào)鏈但中的任意一個回調(diào),您都可以修改或者替換掉他們。當(dāng)請求開始被 處理時,還沒有響應(yīng)對象,響應(yīng)對象將在這一過程中,被某個視圖函數(shù)或者系統(tǒng) 的其他組件按照實際需要來闖將。

但是,如果您想在響應(yīng)過程的結(jié)尾修改響應(yīng)對象,但是這是對象還不存在,那么會發(fā)生 什么呢?一個常見的例子是您可能需要在 before-request 函數(shù)當(dāng)中在響應(yīng)對象上 設(shè)定 Cookie 。

解決這一情況的一個常用方法是改變代碼的邏輯,將這一部分代碼遷移到 after-request 回調(diào)中。然而有些時候這種遷移并不是一個非常容易的敬禮 而且可能使代碼看起來非常糟糕。

一個可能的替代方法是將一些回調(diào)函數(shù)綁定到 g 對象中。然后在 請求結(jié)束的時候調(diào)用他們。使用這種方法,您可以從應(yīng)用里的任何一個地方來指定 代碼延遲執(zhí)行。

裝飾器

下面的裝飾器就是關(guān)鍵,它將一個函數(shù)注冊到 g 對象上的 一個函數(shù)列表中:

from flask import g

def after_this_request(f):
    if not hasattr(g, 'after_request_callbacks'):
        g.after_request_callbacks = []
    g.after_request_callbacks.append(f)
    return f

調(diào)用延遲函數(shù)

現(xiàn)在您可以使用 after_this_request 裝飾器來將一個函數(shù)標(biāo)記為在請求結(jié)束之后 執(zhí)行,但是我們?nèi)匀恍枰謩诱{(diào)用他們。為此,如下函數(shù)將被注冊為 after_request() 回調(diào):

@app.after_request
def call_after_request_callbacks(response):
    for callback in getattr(g, 'after_request_callbacks', ()):
        response = callback(response)
    return response

一個實際應(yīng)用的例子

現(xiàn)在我們可以在任何時間點將一個函數(shù)注冊為在某個特定請求結(jié)束后執(zhí)行,例如您可以 在 before-request 中將用戶當(dāng)前語言的信息保存在 Cookie 中:

from flask import request

@app.before_request
def detect_user_language():
    language = request.cookies.get('user_lang')
    if language is None:
        language = guess_language_from_request()
        @after_this_request
        def remember_language(response):
            response.set_cookie('user_lang', language)
    g.language = language


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號