mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-03 13:14:30 +03:00
More cleanup of browser overrides
This commit is contained in:
parent
d7142e23ac
commit
c64896c849
|
@ -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
|
## 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.
|
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.
|
||||||
|
|
|
@ -249,47 +249,23 @@ Default:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Browser overrides
|
## Content type controls
|
||||||
|
|
||||||
*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'`
|
|
||||||
|
|
||||||
#### URL_FORMAT_OVERRIDE
|
#### 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'`
|
Default: `'format'`
|
||||||
|
|
||||||
|
@ -451,12 +427,6 @@ A string representing the key that should be used for the URL fields generated b
|
||||||
|
|
||||||
Default: `'url'`
|
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
|
#### 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.
|
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.
|
||||||
|
|
|
@ -92,9 +92,6 @@ class DefaultContentNegotiation(BaseContentNegotiation):
|
||||||
"""
|
"""
|
||||||
Given the incoming request, return a tokenised list of media
|
Given the incoming request, return a tokenised list of media
|
||||||
type strings.
|
type strings.
|
||||||
|
|
||||||
Allows URL style accept override. eg. "?accept=application/json"
|
|
||||||
"""
|
"""
|
||||||
header = request.META.get('HTTP_ACCEPT', '*/*')
|
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(',')]
|
return [token.strip() for token in header.split(',')]
|
||||||
|
|
|
@ -22,7 +22,6 @@ def preserve_builtin_query_params(url, request=None):
|
||||||
|
|
||||||
overrides = [
|
overrides = [
|
||||||
api_settings.URL_FORMAT_OVERRIDE,
|
api_settings.URL_FORMAT_OVERRIDE,
|
||||||
api_settings.URL_ACCEPT_OVERRIDE
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for param in overrides:
|
for param in overrides:
|
||||||
|
|
|
@ -91,10 +91,8 @@ DEFAULTS = {
|
||||||
),
|
),
|
||||||
'TEST_REQUEST_DEFAULT_FORMAT': 'multipart',
|
'TEST_REQUEST_DEFAULT_FORMAT': 'multipart',
|
||||||
|
|
||||||
# Browser enhancements
|
# Hyperlink settings
|
||||||
'URL_ACCEPT_OVERRIDE': 'accept',
|
|
||||||
'URL_FORMAT_OVERRIDE': 'format',
|
'URL_FORMAT_OVERRIDE': 'format',
|
||||||
|
|
||||||
'FORMAT_SUFFIX_KWARG': 'format',
|
'FORMAT_SUFFIX_KWARG': 'format',
|
||||||
'URL_FIELD_NAME': 'url',
|
'URL_FIELD_NAME': 'url',
|
||||||
|
|
||||||
|
|
|
@ -191,17 +191,6 @@ class RendererEndToEndTests(TestCase):
|
||||||
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
|
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
|
||||||
self.assertEqual(resp.status_code, DUMMYSTATUS)
|
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):
|
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."""
|
"""If the Accept header is unsatisfiable we should return a 406 Not Acceptable response."""
|
||||||
resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
|
resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
|
||||||
|
|
|
@ -10,7 +10,6 @@ from rest_framework.renderers import (
|
||||||
BaseRenderer, BrowsableAPIRenderer, JSONRenderer
|
BaseRenderer, BrowsableAPIRenderer, JSONRenderer
|
||||||
)
|
)
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.settings import api_settings
|
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from tests.models import BasicModel
|
from tests.models import BasicModel
|
||||||
|
|
||||||
|
@ -176,17 +175,6 @@ class RendererIntegrationTests(TestCase):
|
||||||
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
|
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
|
||||||
self.assertEqual(resp.status_code, DUMMYSTATUS)
|
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):
|
def test_specified_renderer_serializes_content_on_format_query(self):
|
||||||
"""If a 'format' query is specified, the renderer with the matching
|
"""If a 'format' query is specified, the renderer with the matching
|
||||||
format attribute should serialize the response."""
|
format attribute should serialize the response."""
|
||||||
|
@ -299,16 +287,6 @@ class Issue807Tests(TestCase):
|
||||||
resp = self.client.get('/setbyview', **headers)
|
resp = self.client.get('/setbyview', **headers)
|
||||||
self.assertEqual('setbyview', resp['Content-Type'])
|
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):
|
def test_form_has_label_and_help_text(self):
|
||||||
resp = self.client.get('/html_new_model')
|
resp = self.client.get('/html_new_model')
|
||||||
self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8')
|
self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user