aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/renderers.py
diff options
context:
space:
mode:
authorDmitry Mukhin2014-08-20 20:04:48 +0400
committerDmitry Mukhin2014-08-20 20:04:48 +0400
commit3b07d0c9978335e183f369480618b48ff1e1b1ab (patch)
tree041027c50d2965da1be7f93b1a6360e07ad976f9 /rest_framework/renderers.py
parentc3891b6e00daa7a92cca1c88599e046f72926bb4 (diff)
parent59b47eac14778767a17e56bd8adc0610417f2878 (diff)
downloaddjango-rest-framework-3b07d0c9978335e183f369480618b48ff1e1b1ab.tar.bz2
Merge branch 'master' into set-retry-after
Conflicts: tests/test_throttling.py
Diffstat (limited to 'rest_framework/renderers.py')
-rw-r--r--rest_framework/renderers.py71
1 files changed, 42 insertions, 29 deletions
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index 7a7da561..748ebac9 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -8,7 +8,6 @@ REST framework also provides an HTML renderer the renders the browsable API.
"""
from __future__ import unicode_literals
-import copy
import json
import django
from django import forms
@@ -16,11 +15,9 @@ from django.core.exceptions import ImproperlyConfigured
from django.http.multipartparser import parse_header
from django.template import RequestContext, loader, Template
from django.test.client import encode_multipart
+from django.utils import six
from django.utils.xmlutils import SimplerXMLGenerator
-from rest_framework.compat import StringIO
-from rest_framework.compat import six
-from rest_framework.compat import smart_text
-from rest_framework.compat import yaml
+from rest_framework.compat import StringIO, smart_text, yaml
from rest_framework.exceptions import ParseError
from rest_framework.settings import api_settings
from rest_framework.request import is_form_media_type, override_method
@@ -54,35 +51,41 @@ class JSONRenderer(BaseRenderer):
format = 'json'
encoder_class = encoders.JSONEncoder
ensure_ascii = True
- charset = None
- # JSON is a binary encoding, that can be encoded as utf-8, utf-16 or utf-32.
+
+ # We don't set a charset because JSON is a binary encoding,
+ # that can be encoded as utf-8, utf-16 or utf-32.
# See: http://www.ietf.org/rfc/rfc4627.txt
# Also: http://lucumr.pocoo.org/2013/7/19/application-mimetypes-and-encodings/
+ charset = None
+
+ def get_indent(self, accepted_media_type, renderer_context):
+ if accepted_media_type:
+ # If the media type looks like 'application/json; indent=4',
+ # then pretty print the result.
+ base_media_type, params = parse_header(accepted_media_type.encode('ascii'))
+ try:
+ return max(min(int(params['indent']), 8), 0)
+ except (KeyError, ValueError, TypeError):
+ pass
+
+ # If 'indent' is provided in the context, then pretty print the result.
+ # E.g. If we're being called by the BrowsableAPIRenderer.
+ return renderer_context.get('indent', None)
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
- Render `data` into JSON.
+ Render `data` into JSON, returning a bytestring.
"""
if data is None:
return bytes()
- # If 'indent' is provided in the context, then pretty print the result.
- # E.g. If we're being called by the BrowsableAPIRenderer.
renderer_context = renderer_context or {}
- indent = renderer_context.get('indent', None)
+ indent = self.get_indent(accepted_media_type, renderer_context)
- if accepted_media_type:
- # If the media type looks like 'application/json; indent=4',
- # then pretty print the result.
- base_media_type, params = parse_header(accepted_media_type.encode('ascii'))
- indent = params.get('indent', indent)
- try:
- indent = max(min(int(indent), 8), 0)
- except (ValueError, TypeError):
- indent = None
-
- ret = json.dumps(data, cls=self.encoder_class,
- indent=indent, ensure_ascii=self.ensure_ascii)
+ ret = json.dumps(
+ data, cls=self.encoder_class,
+ indent=indent, ensure_ascii=self.ensure_ascii
+ )
# On python 2.x json.dumps() returns bytestrings if ensure_ascii=True,
# but if ensure_ascii=False, the return type is underspecified,
@@ -193,6 +196,7 @@ class YAMLRenderer(BaseRenderer):
format = 'yaml'
encoder = encoders.SafeDumper
charset = 'utf-8'
+ ensure_ascii = True
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
@@ -203,7 +207,15 @@ class YAMLRenderer(BaseRenderer):
if data is None:
return ''
- return yaml.dump(data, stream=None, encoding=self.charset, Dumper=self.encoder)
+ return yaml.dump(data, stream=None, encoding=self.charset, Dumper=self.encoder, allow_unicode=not self.ensure_ascii)
+
+
+class UnicodeYAMLRenderer(YAMLRenderer):
+ """
+ Renderer which serializes to YAML.
+ Does *not* apply character escaping for non-ascii characters.
+ """
+ ensure_ascii = False
class TemplateHTMLRenderer(BaseRenderer):
@@ -400,7 +412,7 @@ class BrowsableAPIRenderer(BaseRenderer):
"""
Returns True if a form should be shown for this method.
"""
- if not method in view.allowed_methods:
+ if method not in view.allowed_methods:
return # Not a valid method
if not api_settings.FORM_METHOD_OVERRIDE:
@@ -440,8 +452,10 @@ class BrowsableAPIRenderer(BaseRenderer):
if method in ('DELETE', 'OPTIONS'):
return True # Don't actually need to return a form
- if (not getattr(view, 'get_serializer', None)
- or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)):
+ if (
+ not getattr(view, 'get_serializer', None)
+ or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
+ ):
return
serializer = view.get_serializer(instance=obj, data=data, files=files)
@@ -562,7 +576,7 @@ class BrowsableAPIRenderer(BaseRenderer):
'version': VERSION,
'breadcrumblist': self.get_breadcrumbs(request),
'allowed_methods': view.allowed_methods,
- 'available_formats': [renderer.format for renderer in view.renderer_classes],
+ 'available_formats': [renderer_cls.format for renderer_cls in view.renderer_classes],
'response_headers': response_headers,
'put_form': self.get_rendered_html_form(view, 'PUT', request),
@@ -611,4 +625,3 @@ class MultiPartRenderer(BaseRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
return encode_multipart(self.BOUNDARY, data)
-