From c64896c849d7dbf13834a5300f7085cf5041d1df Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 28 Sep 2015 15:33:55 +0100 Subject: [PATCH] More cleanup of browser overrides --- docs/api-guide/format-suffixes.md | 10 ++++++ docs/api-guide/settings.md | 56 +++++++------------------------ rest_framework/negotiation.py | 3 -- rest_framework/reverse.py | 1 - rest_framework/settings.py | 4 +-- tests/test_renderers.py | 11 ------ tests/test_response.py | 22 ------------ 7 files changed, 24 insertions(+), 83 deletions(-) diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md index 35dbcd39c..13717b05f 100644 --- a/docs/api-guide/format-suffixes.md +++ b/docs/api-guide/format-suffixes.md @@ -69,6 +69,16 @@ If using the `i18n_patterns` function provided by Django, as well as `format_suf --- +## Query parameter formats + +An alternative to the format suffixes is to include the requested format in a query parameter. REST framework provides this option by default, and it is used in the browsable API to switch between differing available representations. + +To select a representation using its short format, use the `format` query parameter. For example: `http://example.com/organizations/?format=csv`. + +The name of this query parameter can be modified using the `URL_FORMAT_OVERRIDE` setting. Set the value to `None` to disable this behavior. + +--- + ## Accept headers vs. format suffixes There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that `HTTP Accept` headers should always be used instead. diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 13d23a69e..23691dec1 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -249,47 +249,23 @@ Default: --- -## Browser overrides - -*The following settings provide URL or form-based overrides of the default browser behavior.* - -#### FORM_METHOD_OVERRIDE - -The name of a form field that may be used to override the HTTP method of the form. - -If the value of this setting is `None` then form method overloading will be disabled. - -Default: `'_method'` - -#### FORM_CONTENT_OVERRIDE - -The name of a form field that may be used to override the content of the form payload. Must be used together with `FORM_CONTENTTYPE_OVERRIDE`. - -If either setting is `None` then form content overloading will be disabled. - -Default: `'_content'` - -#### FORM_CONTENTTYPE_OVERRIDE - -The name of a form field that may be used to override the content type of the form payload. Must be used together with `FORM_CONTENT_OVERRIDE`. - -If either setting is `None` then form content overloading will be disabled. - -Default: `'_content_type'` - -#### URL_ACCEPT_OVERRIDE - -The name of a URL parameter that may be used to override the HTTP `Accept` header. - -If the value of this setting is `None` then URL accept overloading will be disabled. - -Default: `'accept'` +## Content type controls #### URL_FORMAT_OVERRIDE -The name of a URL parameter that may be used to override the default `Accept` header based content negotiation. +The name of a URL parameter that may be used to override the default content negotiation `Accept` header behavior, by using a `format=…` query parameter in the request URL. -If the value of this setting is `None` then URL format overloading will be disabled. +For example: `http://example.com/organizations/?format=csv` + +If the value of this setting is `None` then URL format overrides will be disabled. + +Default: `'format'` + +#### FORMAT_SUFFIX_KWARG + +The name of a parameter in the URL conf that may be used to provide a format suffix. This setting is applied when using `format_suffix_patterns` to include suffixed URL patterns. + +For example: `http://example.com/organizations.csv/` Default: `'format'` @@ -451,12 +427,6 @@ A string representing the key that should be used for the URL fields generated b Default: `'url'` -#### FORMAT_SUFFIX_KWARG - -The name of a parameter in the URL conf that may be used to provide a format suffix. - -Default: `'format'` - #### NUM_PROXIES An integer of 0 or more, that may be used to specify the number of application proxies that the API runs behind. This allows throttling to more accurately identify client IP addresses. If set to `None` then less strict IP matching will be used by the throttle classes. diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index b9263c447..2a2b6f168 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -92,9 +92,6 @@ class DefaultContentNegotiation(BaseContentNegotiation): """ Given the incoming request, return a tokenised list of media type strings. - - Allows URL style accept override. eg. "?accept=application/json" """ header = request.META.get('HTTP_ACCEPT', '*/*') - header = request.query_params.get(self.settings.URL_ACCEPT_OVERRIDE, header) return [token.strip() for token in header.split(',')] diff --git a/rest_framework/reverse.py b/rest_framework/reverse.py index af7c5e949..5a7ba09a8 100644 --- a/rest_framework/reverse.py +++ b/rest_framework/reverse.py @@ -22,7 +22,6 @@ def preserve_builtin_query_params(url, request=None): overrides = [ api_settings.URL_FORMAT_OVERRIDE, - api_settings.URL_ACCEPT_OVERRIDE ] for param in overrides: diff --git a/rest_framework/settings.py b/rest_framework/settings.py index ddf37d443..9d834c125 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -91,10 +91,8 @@ DEFAULTS = { ), 'TEST_REQUEST_DEFAULT_FORMAT': 'multipart', - # Browser enhancements - 'URL_ACCEPT_OVERRIDE': 'accept', + # Hyperlink settings 'URL_FORMAT_OVERRIDE': 'format', - 'FORMAT_SUFFIX_KWARG': 'format', 'URL_FIELD_NAME': 'url', diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 060d3503a..b4b2db22e 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -191,17 +191,6 @@ class RendererEndToEndTests(TestCase): self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) self.assertEqual(resp.status_code, DUMMYSTATUS) - def test_specified_renderer_serializes_content_on_accept_query(self): - """The '_accept' query string should behave in the same way as the Accept header.""" - param = '?%s=%s' % ( - api_settings.URL_ACCEPT_OVERRIDE, - RendererB.media_type - ) - resp = self.client.get('/' + param) - self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8') - self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) - self.assertEqual(resp.status_code, DUMMYSTATUS) - def test_unsatisfiable_accept_header_on_request_returns_406_status(self): """If the Accept header is unsatisfiable we should return a 406 Not Acceptable response.""" resp = self.client.get('/', HTTP_ACCEPT='foo/bar') diff --git a/tests/test_response.py b/tests/test_response.py index b53688e5c..df2d7b4ec 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -10,7 +10,6 @@ from rest_framework.renderers import ( BaseRenderer, BrowsableAPIRenderer, JSONRenderer ) from rest_framework.response import Response -from rest_framework.settings import api_settings from rest_framework.views import APIView from tests.models import BasicModel @@ -176,17 +175,6 @@ class RendererIntegrationTests(TestCase): self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) self.assertEqual(resp.status_code, DUMMYSTATUS) - def test_specified_renderer_serializes_content_on_accept_query(self): - """The '_accept' query string should behave in the same way as the Accept header.""" - param = '?%s=%s' % ( - api_settings.URL_ACCEPT_OVERRIDE, - RendererB.media_type - ) - resp = self.client.get('/' + param) - self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8') - self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT)) - self.assertEqual(resp.status_code, DUMMYSTATUS) - def test_specified_renderer_serializes_content_on_format_query(self): """If a 'format' query is specified, the renderer with the matching format attribute should serialize the response.""" @@ -299,16 +287,6 @@ class Issue807Tests(TestCase): resp = self.client.get('/setbyview', **headers) self.assertEqual('setbyview', resp['Content-Type']) - def test_viewset_label_help_text(self): - param = '?%s=%s' % ( - api_settings.URL_ACCEPT_OVERRIDE, - 'text/html' - ) - resp = self.client.get('/html_new_model_viewset/' + param) - self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8') - # self.assertContains(resp, 'Text comes here') - # self.assertContains(resp, 'Text description.') - def test_form_has_label_and_help_text(self): resp = self.client.get('/html_new_model') self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8')