diff options
| author | Tom Christie | 2013-02-07 12:57:40 +0000 | 
|---|---|---|
| committer | Tom Christie | 2013-02-07 12:57:40 +0000 | 
| commit | 670ac25b25a3c7fb54fca6aa9344b8250ab49edb (patch) | |
| tree | fdd12baeb96f10d8824d172553dbd6e469e8798d /rest_framework | |
| parent | 8113d661260834a91d91481f31860398cde9212d (diff) | |
| download | django-rest-framework-670ac25b25a3c7fb54fca6aa9344b8250ab49edb.tar.bz2 | |
Allow serializers to handle dicts as well as objects.  Fixes #447.
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/fields.py | 21 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 6 | ||||
| -rw-r--r-- | rest_framework/tests/serializer.py | 27 | 
3 files changed, 47 insertions, 7 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 2c3e59b5..aa6fa3ab 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -30,6 +30,21 @@ def is_simple_callable(obj):      ) +def get_component(obj, attr_name): +    """ +    Given an object, and an attribute name, +    return that attribute on the object. +    """ +    if isinstance(obj, dict): +        val = obj[attr_name] +    else: +        val = getattr(obj, attr_name) + +    if is_simple_callable(val): +        return val() +    return val + +  class Field(object):      read_only = True      creation_counter = 0 @@ -82,11 +97,9 @@ class Field(object):          if self.source:              value = obj              for component in self.source.split('.'): -                value = getattr(value, component) -                if is_simple_callable(value): -                    value = value() +                value = get_component(value, component)          else: -            value = getattr(obj, field_name) +            value = get_component(obj, field_name)          return self.to_native(value)      def to_native(self, value): diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 7daeac41..a6dbf5d7 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -325,7 +325,7 @@ class BaseSerializer(Field):          if self.many is not None:              many = self.many          else: -            many = hasattr(obj, '__iter__') and not isinstance(obj, Page) +            many = hasattr(obj, '__iter__') and not isinstance(obj, (Page, dict))          if many:              return [self.to_native(item) for item in obj] @@ -343,7 +343,7 @@ class BaseSerializer(Field):              if self.many is not None:                  many = self.many              else: -                many = hasattr(data, '__iter__') and not isinstance(data, dict) +                many = hasattr(data, '__iter__') and not isinstance(data, (Page, dict))              # TODO: error data when deserializing lists              if many: @@ -368,7 +368,7 @@ class BaseSerializer(Field):              if self.many is not None:                  many = self.many              else: -                many = hasattr(obj, '__iter__') and not isinstance(obj, Page) +                many = hasattr(obj, '__iter__') and not isinstance(obj, (Page, dict))              if many:                  self._data = [self.to_native(item) for item in obj] diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 62de16ab..2d17e99d 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -185,6 +185,33 @@ class BasicTests(TestCase):          self.assertEquals(instance.age, self.person_data['age']) +class DictStyleSerializer(serializers.Serializer): +    """ +    Note that we don't have any `restore_object` method, so the default +    case of simply returning a dict will apply. +    """ +    email = serializers.EmailField() + + +class DictStyleSerializerTests(TestCase): +    def test_dict_style_deserialize(self): +        """ +        Ensure serializers can deserialize into a dict. +        """ +        data = {'email': 'foo@example.com'} +        serializer = DictStyleSerializer(data=data) +        self.assertTrue(serializer.is_valid()) +        self.assertEquals(serializer.data, data) + +    def test_dict_style_serialize(self): +        """ +        Ensure serializers can serialize dict objects. +        """ +        data = {'email': 'foo@example.com'} +        serializer = DictStyleSerializer(data) +        self.assertEquals(serializer.data, data) + +  class ValidationTests(TestCase):      def setUp(self):          self.comment = Comment(  | 
