Tentative async implementation

This commit is contained in:
enrico 2022-08-19 17:03:22 +08:00
parent df584350b4
commit 79ce07ba9b
2 changed files with 81 additions and 5 deletions

View File

@ -1,6 +1,8 @@
"""
Provides an APIView class that is the base of all views in REST framework.
"""
import asyncio
from asgiref.sync import async_to_sync
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.db import connections, models
@ -503,6 +505,9 @@ class APIView(View):
else:
handler = self.http_method_not_allowed
if asyncio.iscoroutinefunction(handler):
response = async_to_sync(handler)(request, *args, **kwargs)
else:
response = handler(request, *args, **kwargs)
except Exception as exc:

View File

@ -22,16 +22,24 @@ class BasicView(APIView):
return Response({'method': 'POST', 'data': request.data})
class BasicAsyncView(APIView):
async def get(self, request, *args, **kwargs):
return Response({'method': 'GET'})
async def post(self, request, *args, **kwargs):
return Response({'method': 'POST', 'data': request.data})
@api_view(['GET', 'POST', 'PUT', 'PATCH'])
def basic_view(request):
if request.method == 'GET':
return {'method': 'GET'}
return Response({'method': 'GET'})
elif request.method == 'POST':
return {'method': 'POST', 'data': request.data}
return Response({'method': 'POST', 'data': request.data})
elif request.method == 'PUT':
return {'method': 'PUT', 'data': request.data}
return Response({'method': 'PUT', 'data': request.data})
elif request.method == 'PATCH':
return {'method': 'PATCH', 'data': request.data}
return Response({'method': 'PATCH', 'data': request.data})
class ErrorView(APIView):
@ -72,6 +80,23 @@ class ClassBasedViewIntegrationTests(TestCase):
def setUp(self):
self.view = BasicView.as_view()
def test_get_succeeds(self):
request = factory.get('/', content_type='application/json')
response = self.view(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {'method': 'GET'}
# def test_post_succeeds(self):
# request = factory.post('/', {"test": "foo"}, content_type='application/json')
# response = self.view(request)
# import pdb; pdb.set_trace()
# expected = {
# 'method': 'POST',
# 'data': {'test': 'foo'}
# }
# assert response.status_code == status.HTTP_200_OK
# assert response.data == expected
def test_400_parse_error(self):
request = factory.post('/', 'f00bar', content_type='application/json')
response = self.view(request)
@ -86,6 +111,52 @@ class FunctionBasedViewIntegrationTests(TestCase):
def setUp(self):
self.view = basic_view
def test_get_succeeds(self):
request = factory.get('/', content_type='application/json')
response = self.view(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {'method': 'GET'}
# def test_post_succeeds(self):
# request = factory.post('/', {'test': 'foo'}, content_type='application/json')
# response = self.view(request)
# expected = {
# 'method': 'POST',
# 'data': {'test': 'foo'}
# }
# assert response.status_code == status.HTTP_200_OK
# assert response.data == expected
def test_400_parse_error(self):
request = factory.post('/', 'f00bar', content_type='application/json')
response = self.view(request)
expected = {
'detail': JSON_ERROR
}
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert sanitise_json_error(response.data) == expected
class ClassBasedAsyncViewIntegrationTests(TestCase):
def setUp(self):
self.view = BasicAsyncView.as_view()
def test_get_succeeds(self):
request = factory.get('/', content_type='application/json')
response = self.view(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {'method': 'GET'}
# def test_post_succeeds(self):
# request = factory.post('/', {'test': 'foo'}, content_type='application/json')
# response = self.view(request)
# expected = {
# 'method': 'POST',
# 'data': {'test': 'foo'}
# }
# assert response.status_code == status.HTTP_200_OK
# assert response.data == expected
def test_400_parse_error(self):
request = factory.post('/', 'f00bar', content_type='application/json')
response = self.view(request)