This commit is contained in:
Sébastien Béal 2013-01-04 07:41:19 -08:00
commit 7c72acf711
2 changed files with 70 additions and 5 deletions

View File

@ -118,6 +118,7 @@ class BaseSerializer(Field):
self._data = None
self._files = None
self._errors = None
self._instance = instance
#####
# Methods to determine which fields to use when (de)serializing objects.
@ -257,7 +258,7 @@ class BaseSerializer(Field):
You should override this method to control how deserialized objects
are instantiated.
"""
if instance is not None:
if instance is not None and not hasattr(instance, '__iter__'):
instance.update(attrs)
return instance
return attrs
@ -276,7 +277,12 @@ class BaseSerializer(Field):
"""
if hasattr(data, '__iter__') and not isinstance(data, dict):
# TODO: error data when deserializing lists
return (self.from_native(item) for item in data)
objects = []
for i, item in enumerate(data):
if hasattr(self.object, '__iter__'):
self._instance = self.object[i]
objects.append(self.from_native(item, files))
return objects
self._errors = {}
if data is not None or files is not None:
@ -286,7 +292,7 @@ class BaseSerializer(Field):
self._errors['non_field_errors'] = ['No input provided']
if not self._errors:
return self.restore_object(attrs, instance=getattr(self, 'object', None))
return self.restore_object(attrs, instance=getattr(self, '_instance', None))
def field_to_native(self, obj, field_name):
"""
@ -337,7 +343,11 @@ class BaseSerializer(Field):
"""
Save the deserialized object and return it.
"""
self.object.save()
if hasattr(self.object, '__iter__'):
for obj in self.object:
obj.save()
else:
self.object.save()
return self.object

View File

@ -34,7 +34,7 @@ class CommentSerializer(serializers.Serializer):
sub_comment = serializers.Field(source='get_sub_comment.sub_comment')
def restore_object(self, data, instance=None):
if instance is None:
if instance is None or hasattr(instance, '__iter__'):
return Comment(**data)
for key, val in data.items():
setattr(instance, key, val)
@ -881,3 +881,58 @@ class NestedSerializerContextTests(TestCase):
# This will raise RuntimeError if context doesn't get passed correctly to the nested Serializers
AlbumCollectionSerializer(album_collection, context={'context_item': 'album context'}).data
class MultipleObjectsTests(TestCase):
def setUp(self):
self.comments = [Comment(
'tom@example.com',
'Happy new year!',
datetime.datetime(2012, 1, 1)
),
Comment(
'seb@example.com',
'Thank you!',
datetime.datetime(2012, 1, 2)
)]
self.data = [{
'email': 'tom@example.com',
'content': 'Happy new year!',
'created': datetime.datetime(2012, 1, 1),
'sub_comment': 'This wont change'
},
{
'email': 'seb@example.com',
'content': 'Thank you!',
'created': datetime.datetime(2012, 1, 2),
'sub_comment': 'This wont change'
}]
self.expected = [{
'email': 'tom@example.com',
'content': 'Happy new year!',
'created': datetime.datetime(2012, 1, 1),
'sub_comment': 'And Merry Christmas!'
},
{
'email': 'seb@example.com',
'content': 'Thank you!',
'created': datetime.datetime(2012, 1, 2),
'sub_comment': 'And Merry Christmas!'
}]
def test_create(self):
serializer = CommentSerializer(data=self.data)
expected = self.comments
self.assertEquals(serializer.is_valid(), True)
self.assertEquals(serializer.object, expected)
self.assertFalse(serializer.object is expected)
self.assertEquals(serializer.data, self.expected)
def test_update(self):
serializer = CommentSerializer(instance=self.comments, data=self.data)
expected = self.comments
self.assertEquals(serializer.is_valid(), True)
self.assertEquals(serializer.object, expected)
for obj, exp in zip(serializer.object, expected):
self.assertTrue(obj is exp)
self.assertEquals(serializer.data, self.expected)