diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2020-02-12 15:15:00 -0700 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-03-18 19:59:12 +0100 |
| commit | fc0fa72ff4cdbf5861a366e31cb8bbacd44da22d (patch) | |
| tree | d419ce531586808b0a111664907b859cb6d22862 /django/utils/deprecation.py | |
| parent | 3f7e4b16bf58f99c71570ba75dc97db8265071be (diff) | |
Fixed #31224 -- Added support for asynchronous views and middleware.
This implements support for asynchronous views, asynchronous tests,
asynchronous middleware, and an asynchronous test client.
Diffstat (limited to 'django/utils/deprecation.py')
| -rw-r--r-- | django/utils/deprecation.py | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py index 81e7c3a15b..6336558a81 100644 --- a/django/utils/deprecation.py +++ b/django/utils/deprecation.py @@ -1,6 +1,9 @@ +import asyncio import inspect import warnings +from asgiref.sync import sync_to_async + class RemovedInNextVersionWarning(DeprecationWarning): pass @@ -80,14 +83,31 @@ class DeprecationInstanceCheck(type): class MiddlewareMixin: + sync_capable = True + async_capable = True + # RemovedInDjango40Warning: when the deprecation ends, replace with: # def __init__(self, get_response): def __init__(self, get_response=None): self._get_response_none_deprecation(get_response) self.get_response = get_response + self._async_check() super().__init__() + def _async_check(self): + """ + If get_response is a coroutine function, turns us into async mode so + a thread is not consumed during a whole request. + """ + if asyncio.iscoroutinefunction(self.get_response): + # Mark the class as async-capable, but do the actual switch + # inside __call__ to avoid swapping out dunder methods + self._is_coroutine = asyncio.coroutines._is_coroutine + def __call__(self, request): + # Exit out to async mode, if needed + if asyncio.iscoroutinefunction(self.get_response): + return self.__acall__(request) response = None if hasattr(self, 'process_request'): response = self.process_request(request) @@ -96,6 +116,19 @@ class MiddlewareMixin: response = self.process_response(request, response) return response + async def __acall__(self, request): + """ + Async version of __call__ that is swapped in when an async request + is running. + """ + response = None + if hasattr(self, 'process_request'): + response = await sync_to_async(self.process_request)(request) + response = response or await self.get_response(request) + if hasattr(self, 'process_response'): + response = await sync_to_async(self.process_response)(request, response) + return response + def _get_response_none_deprecation(self, get_response): if get_response is None: warnings.warn( |
