aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-05-18 08:55:59 -0700
committerTom Christie2013-05-18 08:55:59 -0700
commitc7fd2435330f094a7ab64f4358d11d6c2967eba1 (patch)
tree3b3fc8d9530037677166d7b793cb842c5ea40357
parent3f47eb7a77fcc735782dd1bf8e8e053e26417ea1 (diff)
parentb9b22976125fffa4552da695183bf75fbaf0b927 (diff)
downloaddjango-rest-framework-c7fd2435330f094a7ab64f4358d11d6c2967eba1.tar.bz2
Merge pull request #863 from pyriku/787-unicodejsonrenderer
Adds UnicodeJSONRenderer
-rw-r--r--docs/api-guide/renderers.md6
-rw-r--r--rest_framework/renderers.py9
-rw-r--r--rest_framework/tests/renderers.py20
3 files changed, 31 insertions, 4 deletions
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index b9a9fd7a..1661ceec 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -67,7 +67,7 @@ If your API includes views that can serve both regular webpages and API response
## JSONRenderer
-Renders the request data into `JSON`.
+Renders the request data into `JSON` enforcing ASCII encoding
The client may additionally include an `'indent'` media type parameter, in which case the returned `JSON` will be indented. For example `Accept: application/json; indent=4`.
@@ -75,6 +75,10 @@ The client may additionally include an `'indent'` media type parameter, in which
**.format**: `'.json'`
+## UnicodeJSONRenderer
+
+Same as `JSONRenderer` but doesn't enforce ASCII encoding
+
## JSONPRenderer
Renders the request data into `JSONP`. The `JSONP` media type provides a mechanism of allowing cross-domain AJAX requests, by wrapping a `JSON` response in a javascript callback.
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index 8361cd40..4345a313 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -49,6 +49,7 @@ class JSONRenderer(BaseRenderer):
media_type = 'application/json'
format = 'json'
encoder_class = encoders.JSONEncoder
+ ensure_ascii = True
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
@@ -72,7 +73,11 @@ class JSONRenderer(BaseRenderer):
except (ValueError, TypeError):
indent = None
- return json.dumps(data, cls=self.encoder_class, indent=indent)
+ return json.dumps(data, cls=self.encoder_class, indent=indent, ensure_ascii=self.ensure_ascii)
+
+
+class UnicodeJSONRenderer(JSONRenderer):
+ ensure_ascii = False
class JSONPRenderer(JSONRenderer):
@@ -320,7 +325,7 @@ class BrowsableAPIRenderer(BaseRenderer):
renderer_context['indent'] = 4
content = renderer.render(data, accepted_media_type, renderer_context)
- if not all(char in string.printable for char in content):
+ if not isinstance(content, six.text_type):
return '[%d bytes of binary content]'
return content
diff --git a/rest_framework/tests/renderers.py b/rest_framework/tests/renderers.py
index 40bac9cb..739f9184 100644
--- a/rest_framework/tests/renderers.py
+++ b/rest_framework/tests/renderers.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
from decimal import Decimal
from django.core.cache import cache
from django.test import TestCase
@@ -8,7 +9,7 @@ from rest_framework.compat import yaml, etree, patterns, url, include
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
- XMLRenderer, JSONPRenderer, BrowsableAPIRenderer
+ XMLRenderer, JSONPRenderer, BrowsableAPIRenderer, UnicodeJSONRenderer
from rest_framework.parsers import YAMLParser, XMLParser
from rest_framework.settings import api_settings
from rest_framework.compat import StringIO
@@ -254,6 +255,23 @@ class JSONRendererTests(TestCase):
content = renderer.render(obj, 'application/json; indent=2')
self.assertEqual(strip_trailing_whitespace(content), _indented_repr)
+ def test_check_ascii(self):
+ obj = {'countries': ['United Kingdom', 'France', 'España']}
+ renderer = JSONRenderer()
+ content = renderer.render(obj, 'application/json')
+ self.assertEqual(content, '{"countries": ["United Kingdom", "France", "Espa\\u00f1a"]}')
+
+
+class UnicodeJSONRendererTests(TestCase):
+ """
+ Tests specific for the Unicode JSON Renderer
+ """
+ def test_proper_encoding(self):
+ obj = {'countries': ['United Kingdom', 'France', 'España']}
+ renderer = UnicodeJSONRenderer()
+ content = renderer.render(obj, 'application/json')
+ self.assertEqual(content, '{"countries": ["United Kingdom", "France", "España"]}')
+
class JSONPRendererTests(TestCase):
"""