Django 中间件如何与异步视图一起使用?

2023-04-11 00:00:00 django 视图 中间件

在 Django 中,中间件可以拦截请求并对其进行处理。对于异步视图(使用 asyncio、aiohttp 等库实现的视图)来说,我们需要使用中间件的异步版本。

具体来说,对于 Django 3.0+,可以使用 async 版本的中间件类,在定义中间件时继承自 AsynMiddlewareMixin。

例如,我们定义一个中间件,在每个请求前后打印出请求 URL 和响应码:

from django.utils.deprecation import MiddlewareMixin

class LoggingMiddleware(MiddlewareMixin):
    async def __call__(self, request):
        print(f"-> {request.method} {request.path}")

        response = await super().__call__(request)

        print(f"<- {response.status_code}")
        return response

注意到这里需要使用 await 来调用父类的__call__方法。

接着,我们在项目配置文件中将这个中间件添加到 MIDDLEWARE 中:

MIDDLEWARE = [
    # ...
    'path.to.LoggingMiddleware',
    # ...
]

这样,我们就可以在每个请求前后打印出对应的信息了。

如果我们需要在视图中使用异步代码,可以使用 async_view 装饰器,例如:

from django.views.decorators.async import async_view
from django.http import JsonResponse

@async_view
async def my_async_view(request):
    data = await fetch_data_from_server()
    return JsonResponse({'data': data})

需要注意的是,这里需要使用 JsonResponse 而不是 HttpResponse,因为前者支持异步响应。同时,由于我们使用了 async_view 装饰器,视图的返回值需要是 awaitable 对象,即使用 async def 定义的协程函数。

最后,我们来演示一下中间件的使用效果。假设我们访问/pidancode,那么控制台上会输出如下信息:

-> GET /pidancode
<- 200

其中,-> 代表请求进入中间件的时候打印的信息,<- 代表在视图执行完成后,中间件再次拦截响应并打印的信息。

相关文章