summaryrefslogtreecommitdiff
path: root/django/utils/deprecation.py
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2020-02-12 15:15:00 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-03-18 19:59:12 +0100
commitfc0fa72ff4cdbf5861a366e31cb8bbacd44da22d (patch)
treed419ce531586808b0a111664907b859cb6d22862 /django/utils/deprecation.py
parent3f7e4b16bf58f99c71570ba75dc97db8265071be (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.py33
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(