Fixed #31224 -- Added support for asynchronous views and middleware.

This implements support for asynchronous views, asynchronous tests,
asynchronous middleware, and an asynchronous test client.
This commit is contained in:
Andrew Godwin 2020-02-12 15:15:00 -07:00 committed by Mariusz Felisiak
parent 3f7e4b16bf
commit fc0fa72ff4
30 changed files with 1344 additions and 214 deletions

View file

@ -1,6 +1,9 @@
from django.http import Http404, HttpResponse
from django.template import engines
from django.template.response import TemplateResponse
from django.utils.decorators import (
async_only_middleware, sync_and_async_middleware, sync_only_middleware,
)
log = []
@ -18,6 +21,12 @@ class ProcessExceptionMiddleware(BaseMiddleware):
return HttpResponse('Exception caught')
@async_only_middleware
class AsyncProcessExceptionMiddleware(BaseMiddleware):
async def process_exception(self, request, exception):
return HttpResponse('Exception caught')
class ProcessExceptionLogMiddleware(BaseMiddleware):
def process_exception(self, request, exception):
log.append('process-exception')
@ -33,6 +42,12 @@ class ProcessViewMiddleware(BaseMiddleware):
return HttpResponse('Processed view %s' % view_func.__name__)
@async_only_middleware
class AsyncProcessViewMiddleware(BaseMiddleware):
async def process_view(self, request, view_func, view_args, view_kwargs):
return HttpResponse('Processed view %s' % view_func.__name__)
class ProcessViewNoneMiddleware(BaseMiddleware):
def process_view(self, request, view_func, view_args, view_kwargs):
log.append('processed view %s' % view_func.__name__)
@ -51,6 +66,13 @@ class TemplateResponseMiddleware(BaseMiddleware):
return response
@async_only_middleware
class AsyncTemplateResponseMiddleware(BaseMiddleware):
async def process_template_response(self, request, response):
response.context_data['mw'].append(self.__class__.__name__)
return response
class LogMiddleware(BaseMiddleware):
def __call__(self, request):
response = self.get_response(request)
@ -63,6 +85,48 @@ class NoTemplateResponseMiddleware(BaseMiddleware):
return None
@async_only_middleware
class AsyncNoTemplateResponseMiddleware(BaseMiddleware):
async def process_template_response(self, request, response):
return None
class NotFoundMiddleware(BaseMiddleware):
def __call__(self, request):
raise Http404('not found')
class TeapotMiddleware(BaseMiddleware):
def __call__(self, request):
response = self.get_response(request)
response.status_code = 418
return response
@async_only_middleware
def async_teapot_middleware(get_response):
async def middleware(request):
response = await get_response(request)
response.status_code = 418
return response
return middleware
@sync_and_async_middleware
class SyncAndAsyncMiddleware(BaseMiddleware):
pass
@sync_only_middleware
class DecoratedTeapotMiddleware(TeapotMiddleware):
pass
class NotSyncOrAsyncMiddleware(BaseMiddleware):
"""Middleware that is deliberately neither sync or async."""
sync_capable = False
async_capable = False
def __call__(self, request):
return self.get_response(request)