Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: python
python:
- "2.7"
- "3.3"
- "3.4"
install:
- pip install -r test_requirements.txt
- pip install . --use-mirrors
Expand Down
7 changes: 6 additions & 1 deletion drf_ujson/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class UJSONParser(BaseParser):
media_type = 'application/json'
renderer_class = JSONRenderer

# Set to enable usage of higher precision (strtod) function when decoding
# string to double values. Default is to use fast but less precise builtin
# functionality.
precise_float = False

def parse(self, stream, media_type=None, parser_context=None):
"""
Parses the incoming bytestream as JSON and returns the resulting data.
Expand All @@ -29,6 +34,6 @@ def parse(self, stream, media_type=None, parser_context=None):

try:
data = stream.read().decode(encoding)
return ujson.loads(data)
return ujson.loads(data, precise_float=self.precise_float)
except ValueError as exc:
raise ParseError('JSON parse error - %s' % six.text_type(exc))
35 changes: 26 additions & 9 deletions drf_ujson/renderers.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
from __future__ import unicode_literals
from rest_framework.compat import six
from rest_framework.renderers import BaseRenderer
from rest_framework.renderers import JSONRenderer
import ujson


class UJSONRenderer(BaseRenderer):
class UJSONRenderer(JSONRenderer):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extending to get get_indent.

"""
Renderer which serializes to JSON.
Applies JSON's backslash-u character escaping for non-ascii characters.
Uses the blazing-fast ujson library for serialization.
"""

media_type = 'application/json'
format = 'json'
ensure_ascii = True
charset = None

def render(self, data, *args, **kwargs):
# Controls how many decimals to encode for double or decimal values.
double_precision = 9
# Controls whether forward slashes (/) are escaped.
escape_forward_slashes = False
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ujson default is True, but I chose False to match standard JSONRenderer.

# Used to enable special encoding of "unsafe" HTML characters into safer
# Unicode sequences.
encode_html_chars = False

def render(self, data, accepted_media_type=None, renderer_context=None):
if data is None:
return bytes()

ret = ujson.dumps(data, ensure_ascii=self.ensure_ascii)
renderer_context = renderer_context or {}
indent = self.get_indent(accepted_media_type, renderer_context)

ret = ujson.dumps(
data,
ensure_ascii=self.ensure_ascii,
escape_forward_slashes=self.escape_forward_slashes,
encode_html_chars=self.encode_html_chars,
double_precision=self.double_precision,
indent=indent or 0,
)

# force return value to unicode
if isinstance(ret, six.text_type):
# We always fully escape \u2028 and \u2029 to ensure we output JSON
# that is a strict javascript subset. If bytes were returned
# by json.dumps() then we don't have these characters in any case.
# See: http://timelessrepo.com/json-isnt-a-javascript-subset
ret = ret.replace('\u2028', '\\u2028').replace('\u2029', '\\u2029')
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying from JSONRenderer.

return bytes(ret.encode('utf-8'))
return ret
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
author_email='[email protected]',
url='https://github.com/gizmag/drf-ujson-renderer',
packages=find_packages(),
install_requires=['django', 'ujson', 'djangorestframework']
install_requires=['django', 'ujson>=1.35', 'djangorestframework']
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version has indent option.

)
2 changes: 1 addition & 1 deletion tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_renderer_works_correctly_when_media_type_and_context_provided(self):

rendered = self.renderer.render(
data=self.data,
media_type='application/json',
accepted_media_type='application/json',
renderer_context={},
)
reloaded = ujson.loads(rendered)
Expand Down