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', 'john@example.com', '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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy