Skip to content

Commit 9f66e8b

Browse files
Ryan P Kilbycarltongibson
authored andcommitted
Fix request body/POST access (#5590)
* Modernize middleware tests * Added a failing test for #5582 * Set data ref on underlying django request
1 parent 15024f3 commit 9f66e8b

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

rest_framework/request.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,10 @@ def _load_data_and_files(self):
250250
else:
251251
self._full_data = self._data
252252

253-
# copy files refs to the underlying request so that closable
253+
# copy data & files refs to the underlying request so that closable
254254
# objects are handled appropriately.
255-
self._request._files = self._files
255+
self._request._post = self.POST
256+
self._request._files = self.FILES
256257

257258
def _load_stream(self):
258259
"""

tests/test_middleware.py

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,76 @@
11
from django.conf.urls import url
22
from django.contrib.auth.models import User
3+
from django.http import HttpRequest
34
from django.test import override_settings
45

56
from rest_framework.authentication import TokenAuthentication
67
from rest_framework.authtoken.models import Token
8+
from rest_framework.request import is_form_media_type
9+
from rest_framework.response import Response
710
from rest_framework.test import APITestCase
811
from rest_framework.views import APIView
912

13+
14+
class PostView(APIView):
15+
def post(self, request):
16+
return Response(data=request.data, status=200)
17+
18+
1019
urlpatterns = [
11-
url(r'^$', APIView.as_view(authentication_classes=(TokenAuthentication,))),
20+
url(r'^auth$', APIView.as_view(authentication_classes=(TokenAuthentication,))),
21+
url(r'^post$', PostView.as_view()),
1222
]
1323

1424

15-
class MyMiddleware(object):
25+
class RequestUserMiddleware(object):
26+
def __init__(self, get_response):
27+
self.get_response = get_response
1628

17-
def process_response(self, request, response):
29+
def __call__(self, request):
30+
response = self.get_response(request)
1831
assert hasattr(request, 'user'), '`user` is not set on request'
19-
assert request.user.is_authenticated(), '`user` is not authenticated'
32+
assert request.user.is_authenticated, '`user` is not authenticated'
33+
34+
return response
35+
36+
37+
class RequestPOSTMiddleware(object):
38+
def __init__(self, get_response):
39+
self.get_response = get_response
40+
41+
def __call__(self, request):
42+
assert isinstance(request, HttpRequest)
43+
44+
# Parse body with underlying Django request
45+
request.body
46+
47+
# Process request with DRF view
48+
response = self.get_response(request)
49+
50+
# Ensure request.POST is set as appropriate
51+
if is_form_media_type(request.content_type):
52+
assert request.POST == {'foo': ['bar']}
53+
else:
54+
assert request.POST == {}
55+
2056
return response
2157

2258

2359
@override_settings(ROOT_URLCONF='tests.test_middleware')
2460
class TestMiddleware(APITestCase):
61+
62+
@override_settings(MIDDLEWARE=('tests.test_middleware.RequestUserMiddleware',))
2563
def test_middleware_can_access_user_when_processing_response(self):
2664
user = User.objects.create_user('john', '[email protected]', 'password')
2765
key = 'abcd1234'
2866
Token.objects.create(key=key, user=user)
2967

30-
with self.settings(
31-
MIDDLEWARE_CLASSES=('tests.test_middleware.MyMiddleware',)
32-
):
33-
auth = 'Token ' + key
34-
self.client.get('/', HTTP_AUTHORIZATION=auth)
68+
self.client.get('/auth', HTTP_AUTHORIZATION='Token %s' % key)
69+
70+
@override_settings(MIDDLEWARE=('tests.test_middleware.RequestPOSTMiddleware',))
71+
def test_middleware_can_access_request_post_when_processing_response(self):
72+
response = self.client.post('/post', {'foo': 'bar'})
73+
assert response.status_code == 200
74+
75+
response = self.client.post('/post', {'foo': 'bar'}, format='json')
76+
assert response.status_code == 200

0 commit comments

Comments
 (0)