Skip to content

Commit d28724e

Browse files
committed
support django 2.1 test client json data automatically serialized
1 parent 101aff6 commit d28724e

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

rest_framework/test.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,19 @@ def _encode_data(self, data, format=None, content_type=None):
152152
Encode the data returning a two tuple of (bytes, content_type)
153153
"""
154154

155-
if data is None:
156-
return ('', content_type)
157-
158155
assert format is None or content_type is None, (
159156
'You may not set both `format` and `content_type`.'
160157
)
161158

162159
if content_type:
160+
try:
161+
data = self._encode_json(data, content_type)
162+
except AttributeError:
163+
pass
164+
165+
if data is None:
166+
data = ''
167+
163168
# Content type specified explicitly, treat data as a raw bytestring
164169
ret = force_bytes(data, settings.DEFAULT_CHARSET)
165170

@@ -177,7 +182,6 @@ def _encode_data(self, data, format=None, content_type=None):
177182

178183
# Use format and render the data into a bytestring
179184
renderer = self.renderer_classes[format]()
180-
ret = renderer.render(data)
181185

182186
# Determine the content-type header from the renderer
183187
content_type = renderer.media_type
@@ -186,6 +190,11 @@ def _encode_data(self, data, format=None, content_type=None):
186190
content_type, renderer.charset
187191
)
188192

193+
if data is None:
194+
ret = ''
195+
else:
196+
ret = renderer.render(data)
197+
189198
# Coerce text to bytes if required.
190199
if isinstance(ret, str):
191200
ret = ret.encode(renderer.charset)

tests/test_testing.py

+25-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from django.test import TestCase, override_settings
1010
from django.urls import path
1111

12-
from rest_framework import fields, serializers
13-
from rest_framework.decorators import api_view
12+
from rest_framework import fields, parsers, serializers
13+
from rest_framework.decorators import api_view, parser_classes
1414
from rest_framework.response import Response
1515
from rest_framework.test import (
1616
APIClient, APIRequestFactory, URLPatternsTestCase, force_authenticate
@@ -48,6 +48,12 @@ class BasicSerializer(serializers.Serializer):
4848
flag = fields.BooleanField(default=lambda: True)
4949

5050

51+
@api_view(['POST'])
52+
@parser_classes((parsers.JSONParser,))
53+
def post_json_view(request):
54+
return Response(request.data)
55+
56+
5157
@api_view(['POST'])
5258
def post_view(request):
5359
serializer = BasicSerializer(data=request.data)
@@ -60,7 +66,8 @@ def post_view(request):
6066
path('session-view/', session_view),
6167
path('redirect-view/', redirect_view),
6268
path('redirect-view/<int:code>/', redirect_307_308_view),
63-
path('post-view/', post_view)
69+
path('post-json-view/', post_json_view),
70+
path('post-view/', post_view),
6471
]
6572

6673

@@ -201,6 +208,21 @@ def test_empty_post_uses_default_boolean_value(self):
201208
assert response.status_code == 200
202209
assert response.data == {"flag": True}
203210

211+
def test_post_encodes_data_based_on_json_content_type(self):
212+
data = {'data': True}
213+
response = self.client.post(
214+
'/post-json-view/',
215+
data=data,
216+
content_type='application/json'
217+
)
218+
219+
if django.VERSION < (2, 1):
220+
assert response.status_code == 400
221+
assert response.data['detail'].code == 'parse_error'
222+
else:
223+
assert response.status_code == 200
224+
assert response.data == data
225+
204226

205227
class TestAPIRequestFactory(TestCase):
206228
def test_csrf_exempt_by_default(self):

0 commit comments

Comments
 (0)