aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2012-09-03 13:30:20 +0100
committerTom Christie2012-09-03 13:30:20 +0100
commita25b4be4418a2a94e38a77b13cc234ca68e8322c (patch)
tree8b14904314ed87d8f0f15bc2a6ebb30c1cf570b9
parentebbaff0853d49cd436b416beeb28220922bfc977 (diff)
downloaddjango-rest-framework-a25b4be4418a2a94e38a77b13cc234ca68e8322c.tar.bz2
Support generators
-rw-r--r--djangorestframework/renderers.py5
-rw-r--r--djangorestframework/tests/renderers.py14
-rw-r--r--djangorestframework/utils/encoders.py33
-rw-r--r--docs/tutorial/1-serialization.md2
4 files changed, 50 insertions, 4 deletions
diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py
index 8d103025..70c0dc88 100644
--- a/djangorestframework/renderers.py
+++ b/djangorestframework/renderers.py
@@ -6,12 +6,12 @@ by serializing the output along with documentation regarding the View, output st
and providing forms and links depending on the allowed methods, renderers and parsers on the View.
"""
from django import forms
-from django.core.serializers.json import DateTimeAwareJSONEncoder
from django.template import RequestContext, loader
from django.utils import simplejson as json
from djangorestframework.compat import yaml
from djangorestframework.utils import dict2xml
+from djangorestframework.utils import encoders
from djangorestframework.utils.breadcrumbs import get_breadcrumbs
from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches
from djangorestframework import VERSION
@@ -94,6 +94,7 @@ class JSONRenderer(BaseRenderer):
media_type = 'application/json'
format = 'json'
+ encoder_class = encoders.JSONEncoder
def render(self, obj=None, media_type=None):
"""
@@ -112,7 +113,7 @@ class JSONRenderer(BaseRenderer):
except (ValueError, TypeError):
indent = None
- return json.dumps(obj, cls=DateTimeAwareJSONEncoder, indent=indent, sort_keys=sort_keys)
+ return json.dumps(obj, cls=self.encoder_class, indent=indent, sort_keys=sort_keys)
class JSONPRenderer(JSONRenderer):
diff --git a/djangorestframework/tests/renderers.py b/djangorestframework/tests/renderers.py
index 1943d012..adf8d8fa 100644
--- a/djangorestframework/tests/renderers.py
+++ b/djangorestframework/tests/renderers.py
@@ -22,6 +22,18 @@ RENDERER_A_SERIALIZER = lambda x: 'Renderer A: %s' % x
RENDERER_B_SERIALIZER = lambda x: 'Renderer B: %s' % x
+expected_results = [
+ ((elem for elem in [1, 2, 3]), JSONRenderer, '[1, 2, 3]') # Generator
+]
+
+
+class BasicRendererTests(TestCase):
+ def test_expected_results(self):
+ for value, renderer_cls, expected in expected_results:
+ output = renderer_cls().render(value)
+ self.assertEquals(output, expected)
+
+
class RendererA(BaseRenderer):
media_type = 'mock/renderera'
format = "formata"
@@ -286,7 +298,7 @@ if YAMLRenderer:
obj = {'foo': ['bar', 'baz']}
renderer = YAMLRenderer(None)
- parser = YAMLParser(None)
+ parser = YAMLParser()
content = renderer.render(obj, 'application/yaml')
(data, files) = parser.parse(StringIO(content))
diff --git a/djangorestframework/utils/encoders.py b/djangorestframework/utils/encoders.py
new file mode 100644
index 00000000..3cd2e8e1
--- /dev/null
+++ b/djangorestframework/utils/encoders.py
@@ -0,0 +1,33 @@
+import datetime
+import decimal
+from django.utils import timezone
+from django.utils import simplejson as json
+
+
+class JSONEncoder(json.JSONEncoder):
+ """
+ JSONEncoder subclass that knows how to encode date/time and decimal types.
+ """
+ def default(self, o):
+ # See "Date Time String Format" in the ECMA-262 specification.
+ if isinstance(o, datetime.datetime):
+ r = o.isoformat()
+ if o.microsecond:
+ r = r[:23] + r[26:]
+ if r.endswith('+00:00'):
+ r = r[:-6] + 'Z'
+ return r
+ elif isinstance(o, datetime.date):
+ return o.isoformat()
+ elif isinstance(o, datetime.time):
+ if timezone.is_aware(o):
+ raise ValueError("JSON can't represent timezone-aware times.")
+ r = o.isoformat()
+ if o.microsecond:
+ r = r[:12]
+ return r
+ elif isinstance(o, decimal.Decimal):
+ return str(o)
+ elif hasattr(o, '__iter__'):
+ return [i for i in o]
+ return super(JSONEncoder, self).default(o)
diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md
index 3cfcf871..13dcb9cc 100644
--- a/docs/tutorial/1-serialization.md
+++ b/docs/tutorial/1-serialization.md
@@ -17,7 +17,7 @@ Now that we're inside a virtualenv environment, we can install our package requi
pip install django
pip install djangorestframework
-***Note:** To exit the virtualenv environment at any time, just type `deactivate`. For more information see the [virtualenv documentation][virtualenv].*
+**Note:** To exit the virtualenv environment at any time, just type `deactivate`. For more information see the [virtualenv documentation][virtualenv].
## Getting started