Skip to content

Commit d579cc1

Browse files
committed
support django 2.1 test client json data automatically serialized
1 parent d32346b commit d579cc1

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

rest_framework/test.py

Lines changed: 13 additions & 4 deletions
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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
from django.test import TestCase, override_settings
1010
from django.urls import path
1111

12-
from rest_framework import fields, serializers
12+
from rest_framework import fields, parsers, serializers
1313
from rest_framework.authtoken.models import Token
14-
from rest_framework.decorators import api_view
14+
from rest_framework.decorators import api_view, parser_classes
1515
from rest_framework.response import Response
1616
from rest_framework.test import (
1717
APIClient, APIRequestFactory, URLPatternsTestCase, force_authenticate
@@ -51,6 +51,12 @@ class BasicSerializer(serializers.Serializer):
5151
flag = fields.BooleanField(default=lambda: True)
5252

5353

54+
@api_view(['POST'])
55+
@parser_classes((parsers.JSONParser,))
56+
def post_json_view(request):
57+
return Response(request.data)
58+
59+
5460
@api_view(['POST'])
5561
def post_view(request):
5662
serializer = BasicSerializer(data=request.data)
@@ -63,7 +69,8 @@ def post_view(request):
6369
path('session-view/', session_view),
6470
path('redirect-view/', redirect_view),
6571
path('redirect-view/<int:code>/', redirect_307_308_view),
66-
path('post-view/', post_view)
72+
path('post-json-view/', post_json_view),
73+
path('post-view/', post_view),
6774
]
6875

6976

@@ -237,6 +244,17 @@ def test_empty_post_uses_default_boolean_value(self):
237244
assert response.status_code == 200
238245
assert response.data == {"flag": True}
239246

247+
def test_post_encodes_data_based_on_json_content_type(self):
248+
data = {'data': True}
249+
response = self.client.post(
250+
'/post-json-view/',
251+
data=data,
252+
content_type='application/json'
253+
)
254+
255+
assert response.status_code == 200
256+
assert response.data == data
257+
240258

241259
class TestAPIRequestFactory(TestCase):
242260
def test_csrf_exempt_by_default(self):

0 commit comments

Comments
 (0)