diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index 238382364..3f76a0252 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -60,6 +60,9 @@ class JSONParser(BaseParser): parser_context = parser_context or {} encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) + if not stream: + return {} + try: data = stream.read().decode(encoding) return json.loads(data) diff --git a/rest_framework/request.py b/rest_framework/request.py index 0a827728a..3ffcadde3 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -298,7 +298,7 @@ class Request(object): return (self._request.POST, self._request.FILES) stream = None - if stream is None or media_type is None: + if stream is None and not media_type: empty_data = QueryDict('', encoding=self._request._encoding) empty_files = MultiValueDict() return (empty_data, empty_files) diff --git a/tests/test_request.py b/tests/test_request.py index dbfa695fd..e1a3a83ff 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -13,7 +13,9 @@ from django.utils import six from rest_framework import status from rest_framework.authentication import SessionAuthentication -from rest_framework.parsers import BaseParser, FormParser, MultiPartParser +from rest_framework.parsers import ( + BaseParser, FormParser, JSONParser, MultiPartParser +) from rest_framework.request import Request from rest_framework.response import Response from rest_framework.test import APIClient, APIRequestFactory @@ -50,6 +52,16 @@ class TestContentParsing(TestCase): request = Request(factory.head('/')) self.assertEqual(request.data, {}) + def test_empty_body_yields_empty_dict_for_json_POST(self): + """ + Ensure request.data returns empty dict for POST request with JSON + content type. + """ + request = Request(factory.post('/', CONTENT_TYPE='application/json')) + request.parsers = (JSONParser(),) + self.assertEquals(type(request.data), dict) + self.assertEquals(request.data, {}) + def test_request_DATA_with_form_content(self): """ Ensure request.data returns content for POST request with form content.