Fix issue #3951: Request.data empty when multipart/form-data POSTed

This commit is contained in:
CaffeineFueled 2016-04-02 18:47:54 -04:00
parent 3d3b06447f
commit 3d27469196
2 changed files with 34 additions and 0 deletions

View File

@ -97,9 +97,14 @@ class MultiPartParser(BaseParser):
`.data` will be a `QueryDict` containing all the form parameters. `.data` will be a `QueryDict` containing all the form parameters.
`.files` will be a `QueryDict` containing all the form files. `.files` will be a `QueryDict` containing all the form files.
For POSTs, accept Django request parsing. See issue #3951.
""" """
parser_context = parser_context or {} parser_context = parser_context or {}
request = parser_context['request'] 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) encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
meta = request.META.copy() meta = request.META.copy()
meta['CONTENT_TYPE'] = media_type meta['CONTENT_TYPE'] = media_type

View File

@ -8,6 +8,7 @@ from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory as DjangoRequestFactory
from django.utils import six from django.utils import six
from rest_framework import status from rest_framework import status
@ -18,6 +19,8 @@ from rest_framework.response import Response
from rest_framework.test import APIClient, APIRequestFactory from rest_framework.test import APIClient, APIRequestFactory
from rest_framework.views import APIView from rest_framework.views import APIView
django_factory = DjangoRequestFactory()
factory = APIRequestFactory() factory = APIRequestFactory()
@ -58,6 +61,19 @@ class TestContentParsing(TestCase):
request.parsers = (FormParser(), MultiPartParser()) request.parsers = (FormParser(), MultiPartParser())
self.assertEqual(list(request.data.items()), list(data.items())) 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): def test_request_DATA_with_text_content(self):
""" """
Ensure request.data returns content for POST request with Ensure request.data returns content for POST request with
@ -78,6 +94,19 @@ class TestContentParsing(TestCase):
request.parsers = (FormParser(), MultiPartParser()) request.parsers = (FormParser(), MultiPartParser())
self.assertEqual(list(request.POST.items()), list(data.items())) 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): def test_standard_behaviour_determines_form_content_PUT(self):
""" """
Ensure request.data returns content for PUT request with form content. Ensure request.data returns content for PUT request with form content.