Repository: encode/django-rest-framework

Issue:
JSON indent parameter in Accept header ignored 
Refactoring between 3.3.3 and 3.4.0 changed how `Response.render` passes `media_type` to its `renderer`.

[Response](https://github.com/tomchristie/django-rest-framework/blob/e476c222f98c4a455bf806fa05c5d70a9e0f37da/rest_framework/response.py#L60) sets it as `media_type = renderer.media_type` compared to `self.accepted_media_type` (set via `APIView.finalize_response` [here](https://github.com/tomchristie/django-rest-framework/blob/e476c222f98c4a455bf806fa05c5d70a9e0f37da/rest_framework/views.py#L405)).

Since `renderer.media_type` looses the indent parameter (i.e. `application/json; indent=4` becomes `application/json`), the resulting JSON rendering is not indented.

A 'simple' fix is to restore the 3.3.3 code where `media_type = getattr(self, 'accepted_media_type', None)` but I haven't made a PR yet because I'm not clear as to whether there was a specific reason for changing to `renderer.media_type` (which might have overlooked that it doesn't include `indent`).



Discussion:
I can confirm, the media_type value that get_ident receives is stripped of params.


Resolving patch:
diff --git a/rest_framework/response.py b/rest_framework/response.py
--- a/rest_framework/response.py
+++ b/rest_framework/response.py
@@ -51,9 +51,11 @@ def __init__(self, data=None, status=None,
     @property
     def rendered_content(self):
         renderer = getattr(self, 'accepted_renderer', None)
+        accepted_media_type = getattr(self, 'accepted_media_type', None)
         context = getattr(self, 'renderer_context', None)
 
         assert renderer, ".accepted_renderer not set on Response"
+        assert accepted_media_type, ".accepted_media_type not set on Response"
         assert context, ".renderer_context not set on Response"
         context['response'] = self
 
@@ -67,7 +69,7 @@ def rendered_content(self):
             content_type = media_type
         self['Content-Type'] = content_type
 
-        ret = renderer.render(self.data, media_type, context)
+        ret = renderer.render(self.data, accepted_media_type, context)
         if isinstance(ret, six.text_type):
             assert charset, (
                 'renderer returned unicode, and did not specify '
diff --git a/rest_framework/routers.py b/rest_framework/routers.py
--- a/rest_framework/routers.py
+++ b/rest_framework/routers.py
@@ -276,6 +276,8 @@ class DefaultRouter(SimpleRouter):
     default_schema_renderers = [renderers.CoreJSONRenderer]
 
     def __init__(self, *args, **kwargs):
+        if 'schema_renderers' in kwargs:
+            assert 'schema_title' in kwargs, 'Missing "schema_title" argument.'
         self.schema_title = kwargs.pop('schema_title', None)
         self.schema_renderers = kwargs.pop('schema_renderers', self.default_schema_renderers)
         super(DefaultRouter, self).__init__(*args, **kwargs)


Test patch:
diff --git a/tests/test_negotiation.py b/tests/test_negotiation.py
--- a/tests/test_negotiation.py
+++ b/tests/test_negotiation.py
@@ -10,6 +10,11 @@
 factory = APIRequestFactory()
 
 
+class MockOpenAPIRenderer(BaseRenderer):
+    media_type = 'application/openapi+json;version=2.0'
+    format = 'swagger'
+
+
 class MockJSONRenderer(BaseRenderer):
     media_type = 'application/json'
 
@@ -24,7 +29,7 @@ class NoCharsetSpecifiedRenderer(BaseRenderer):
 
 class TestAcceptedMediaType(TestCase):
     def setUp(self):
-        self.renderers = [MockJSONRenderer(), MockHTMLRenderer()]
+        self.renderers = [MockJSONRenderer(), MockHTMLRenderer(), MockOpenAPIRenderer()]
         self.negotiator = DefaultContentNegotiation()
 
     def select_renderer(self, request):
@@ -44,3 +49,9 @@ def test_client_overspecifies_accept_use_client(self):
         request = Request(factory.get('/', HTTP_ACCEPT='application/json; indent=8'))
         accepted_renderer, accepted_media_type = self.select_renderer(request)
         self.assertEqual(accepted_media_type, 'application/json; indent=8')
+
+    def test_client_specifies_parameter(self):
+        request = Request(factory.get('/', HTTP_ACCEPT='application/openapi+json;version=2.0'))
+        accepted_renderer, accepted_media_type = self.select_renderer(request)
+        self.assertEqual(accepted_media_type, 'application/openapi+json;version=2.0')
+        self.assertEqual(accepted_renderer.format, 'swagger')