diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index ab74a6e58a..858edc118e 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -97,9 +97,14 @@ def parse(self, stream, media_type=None, parser_context=None): `.data` will be a `QueryDict` containing all the form parameters. `.files` will be a `QueryDict` containing all the form files. + + For POSTs, accept Django request parsing. See issue #3951. """ parser_context = parser_context or {} request = parser_context['request'] + _request = request._request + if _request.method == 'POST': + return DataAndFiles(_request.POST, _request.FILES) encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) meta = request.META.copy() meta['CONTENT_TYPE'] = media_type diff --git a/tests/test_request.py b/tests/test_request.py index 7a0575789a..33d89b3ee7 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -8,6 +8,7 @@ from django.contrib.auth.models import User from django.contrib.sessions.middleware import SessionMiddleware from django.test import TestCase +from django.test.client import RequestFactory as DjangoRequestFactory from django.utils import six from rest_framework import status @@ -18,6 +19,7 @@ from rest_framework.test import APIClient, APIRequestFactory from rest_framework.views import APIView +django_factory = DjangoRequestFactory() factory = APIRequestFactory() @@ -58,6 +60,19 @@ def test_request_DATA_with_form_content(self): request.parsers = (FormParser(), MultiPartParser()) self.assertEqual(list(request.data.items()), list(data.items())) + def test_request_DATA_with_form_content_after_django_peek(self): + """ + Ensure request.data returns content for POST request with form content + after Django has had a look at the POST data (issue #3951). + """ + data = {'qwerty': 'uiop'} + django_request = django_factory.post('/', data) + # Force Django to exhaust the POST stream + django_request.POST + request = Request(django_request) + request.parsers = (FormParser(), MultiPartParser()) + self.assertEqual(list(request.data.items()), list(data.items())) + def test_request_DATA_with_text_content(self): """ Ensure request.data returns content for POST request with @@ -78,6 +93,19 @@ def test_request_POST_with_form_content(self): request.parsers = (FormParser(), MultiPartParser()) self.assertEqual(list(request.POST.items()), list(data.items())) + def test_request_POST_with_form_content_after_django_peek(self): + """ + Ensure request.POST returns content for POST request with form content + after Django has had a look at the POST data (issue #3951). + """ + data = {'qwerty': 'uiop'} + django_request = django_factory.post('/', data) + # Force Django to exhaust the POST stream + django_request.POST + request = Request(django_request) + request.parsers = (FormParser(), MultiPartParser()) + self.assertEqual(list(request.POST.items()), list(data.items())) + def test_standard_behaviour_determines_form_content_PUT(self): """ Ensure request.data returns content for PUT request with form content. 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