Django4.0 中間件-異步支持

2022-03-16 17:47 更新

中間件支持同步和異步請(qǐng)求的任意組合。如果Django不能同時(shí)支持它們,它會(huì)調(diào)整請(qǐng)求來(lái)適應(yīng)中間件的需求,但會(huì)有性能損失。

默認(rèn)情況下,Django假設(shè)你的中間件只能處理同步請(qǐng)求。如果要改變這種模式,需要在你的中間件工廠函數(shù)或類中添加入如下屬性:

  • ?sync_capable ?是一個(gè)布爾值,來(lái)表明中間件是否處理同步請(qǐng)求。默認(rèn)為 ?True?。
  • ?async_capable ?是一個(gè)布爾值,來(lái)表明中間件是否處理異步請(qǐng)求。默認(rèn)為 ?False?。

如果中間件的?sync_capable = True?并且 ?async_capable = True?,那么Django 會(huì)將請(qǐng)求傳遞給它而不進(jìn)行轉(zhuǎn)換。在這種情況下,你可以使用 ?asyncio.iscoroutinefunction()? 來(lái)檢查傳遞的 ?get_response? 是否是一個(gè)協(xié)同函數(shù),從而確定中間件是否接收到異步請(qǐng)求。
?django.utils.decorators? 模塊包含 ?sync_only_middleware()?,?async_only_middleware()? 和 ?sync_and_async_middleware()? 裝飾器,允許你將這些標(biāo)志應(yīng)用到中間件工廠函數(shù)中。
返回的可調(diào)用對(duì)象必須符合 ?get_response ?方法的同步或異步性質(zhì)。如果你有一個(gè)異步的 ?get_response?,你必須返回一個(gè)協(xié)程函數(shù)(?async def?)。
?process_view?、?process_template_response ?和 ?process_exception ?方法,如果有的話,也應(yīng)該進(jìn)行調(diào)整以匹配同步/異步模式。然而,如果你不這樣做,Django 會(huì)根據(jù)需要單獨(dú)調(diào)整它們,但會(huì)有額外的性能損失。
下面以一個(gè)例子來(lái)說(shuō)明如何創(chuàng)建一個(gè)支持這兩種功能的中間件函數(shù):

import asyncio
from django.utils.decorators import sync_and_async_middleware

@sync_and_async_middleware
def simple_middleware(get_response):
    # One-time configuration and initialization goes here.
    if asyncio.iscoroutinefunction(get_response):
        async def middleware(request):
            # Do something here!
            response = await get_response(request)
            return response

    else:
        def middleware(request):
            # Do something here!
            response = get_response(request)
            return response

    return middleware

注解:如果你聲明了一個(gè)同時(shí)支持同步和異步調(diào)用的混合中間件,你得到的調(diào)用種類可能與底層視圖不匹配。Django 會(huì)優(yōu)化中間件調(diào)用棧,使其盡可能少的同步/異步轉(zhuǎn)換。

因此,即使你包裝的是一個(gè)異步視圖,如果在你和視圖之間有其他的、同步的中間件,你也可能會(huì)在同步模式下被調(diào)用。


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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)