aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-12-09 08:50:31 +0000
committerTom Christie2013-12-09 08:50:31 +0000
commita6ca943faa42af30075e260a01d7e672f706d3fd (patch)
tree0e8b0229b0562906ae5541f81fc1d4ca3f024f8f
parentc1be503308e755d72aae2c9695739bd33631e18b (diff)
parent6af31ed3945fd051a6e8c08851d7a656637d1f00 (diff)
downloaddjango-rest-framework-a6ca943faa42af30075e260a01d7e672f706d3fd.tar.bz2
Merge branch 'issue-1231-jsonencoder' of git://github.com/mbox/django-rest-framework into mbox-issue-1231-jsonencoder
-rw-r--r--rest_framework/tests/test_renderers.py57
-rw-r--r--rest_framework/utils/encoders.py6
2 files changed, 63 insertions, 0 deletions
diff --git a/rest_framework/tests/test_renderers.py b/rest_framework/tests/test_renderers.py
index d13b3492..d720bc51 100644
--- a/rest_framework/tests/test_renderers.py
+++ b/rest_framework/tests/test_renderers.py
@@ -18,6 +18,9 @@ from rest_framework.test import APIRequestFactory
import datetime
import pickle
import re
+import UserDict
+import collections
+import json
DUMMYSTATUS = status.HTTP_200_OK
@@ -274,6 +277,60 @@ class JSONRendererTests(TestCase):
ret = JSONRenderer().render(_('test'))
self.assertEqual(ret, b'"test"')
+ def test_render_userdict_obj(self):
+ class DictLike(UserDict.DictMixin):
+ def __init__(self):
+ self._dict = dict()
+ def __getitem__(self, key):
+ return self._dict.__getitem__(key)
+ def __setitem__(self, key, value):
+ return self._dict.__setitem__(key, value)
+ def __delitem__(self, key):
+ return self._dict.__delitem__(key)
+ def keys(self):
+ return self._dict.keys()
+ x = DictLike()
+ x['a'] = 1
+ x['b'] = "string value"
+ ret = JSONRenderer().render(x)
+ self.assertEquals(json.loads(ret), {'a': 1, 'b': 'string value'})
+
+ def test_render_dict_abc_obj(self):
+ class Dict(collections.MutableMapping):
+ def __init__(self):
+ self._dict = dict()
+ def __getitem__(self, key):
+ return self._dict.__getitem__(key)
+ def __setitem__(self, key, value):
+ return self._dict.__setitem__(key, value)
+ def __delitem__(self, key):
+ return self._dict.__delitem__(key)
+ def __iter__(self):
+ return self._dict.__iter__()
+ def __len__(self):
+ return self._dict.__len__()
+
+ x = Dict()
+ x['key'] = 'string value'
+ x[2] = 3
+ ret = JSONRenderer().render(x)
+ self.assertEquals(json.loads(ret), {'key': 'string value', '2': 3})
+
+
+ def test_render_obj_with_getitem(self):
+ class DictLike(object):
+ def __init__(self):
+ self._dict = {}
+ def set(self, value):
+ self._dict = dict(value)
+ def __getitem__(self, key):
+ return self._dict[key]
+
+ x = DictLike()
+ x.set({'a': 1, 'b': 'string'})
+ with self.assertRaises(TypeError):
+ JSONRenderer().render(x)
+
def test_without_content_type_args(self):
"""
Test basic JSON rendering.
diff --git a/rest_framework/utils/encoders.py b/rest_framework/utils/encoders.py
index 35ad206b..22b1ab3d 100644
--- a/rest_framework/utils/encoders.py
+++ b/rest_framework/utils/encoders.py
@@ -44,6 +44,12 @@ class JSONEncoder(json.JSONEncoder):
return str(o)
elif hasattr(o, 'tolist'):
return o.tolist()
+ elif hasattr(o, '__getitem__'):
+ try:
+ return dict(o)
+ except KeyError:
+ # Couldn't convert to a dict, fall through
+ pass
elif hasattr(o, '__iter__'):
return [i for i in o]
return super(JSONEncoder, self).default(o)