I'm using Django Rest Framework (version 3.6.2) to create REST API. I've defined my viewset that inherits from GenericViewSet
and have overriden retrieve
method to implement custom behaviour.
class FooViewSet(viewsets.GenericViewSet):
serializer_class = FooSerializer
def retrieve(self, request, *args, **kwargs):
...
serializer = self.get_serializer(data)
return Response(serializer.data)
I want to have BrowsableAPI while accessing this endpoint from the browser and receive json
response when accessing this endpoint e.g. from the code. I've configured DRF with the following settings:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'TEST_REQUEST_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'TEST_REQUEST_DEFAULT_FORMAT':'json'
}
Everything works as expected, I can access the browsable API from the browser and when making request with the Postman tool I get json response. Unfortunately, I can't achieve the same result during tests.
class GetFooDetailViewTest(APITestCase):
def test_get_should_return_json(self):
response = self.client.get(self.VIEW_URL)
self.assertEqual(response.content_type, "application/json")
I expect the response to have content_type set to application/json
(this is the header that I can see in the responses from browser and Postman). But this test fails - response.content_type
is set to None
. While debugging this test, I've discovered that response._headers
dictionary looks like this
{
'vary': ('Vary', 'Cookie'),
'x-frame-options': ('X-Frame-Options', 'SAMEORIGIN'),
'content-type': ('Content-Type', 'application/json'),
'allow': ('Allow', 'GET, PUT, DELETE, OPTIONS')
}
So it seems like the correct header is being set, but it's not getting populated to the content_type
attribute. Am I missing something?
This is how I test for the content type. In very few cases my code decides the content-type itself, so I to check that I personally did not do something wrong. DRF code is already tested.
self.assertEqual("application/json", resp['Content-Type'])
You just have to rely on DRF doing it right, its not something you can or need to test. For example, you don't test that DRF parsed your json body correctly. The test server isn't exactly like the real one, but its pretty close. For example, you will get real objects out of response.data, not the json encoded/decoded ones.
Check out the LiveServerTestCase if you need it, but it will be slower.