More cleanup of browser overrides

This commit is contained in:
Tom Christie 2015-09-28 15:33:55 +01:00
parent d7142e23ac
commit c64896c849
7 changed files with 24 additions and 83 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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(',')]

View File

@ -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:

View File

@ -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',

View File

@ -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')

View File

@ -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')