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

2021-08-11 10:34 更新

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

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

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

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

裝飾器

下面的裝飾器就是關(guān)鍵,它將一個(gè)函數(shù)注冊(cè)到 g 對(duì)象上的 一個(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 裝飾器來(lái)將一個(gè)函數(shù)標(biāo)記為在請(qǐng)求結(jié)束之后 執(zhí)行,但是我們?nèi)匀恍枰謩?dòng)調(diào)用他們。為此,如下函數(shù)將被注冊(cè)為 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

一個(gè)實(shí)際應(yīng)用的例子

現(xiàn)在我們可以在任何時(shí)間點(diǎn)將一個(gè)函數(shù)注冊(cè)為在某個(gè)特定請(qǐng)求結(jié)束后執(zhí)行,例如您可以 在 before-request 中將用戶(hù)當(dāng)前語(yǔ)言的信息保存在 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)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)