aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/serializers.py
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework/serializers.py')
-rw-r--r--rest_framework/serializers.py37
1 files changed, 21 insertions, 16 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index ba9e9e9c..2ae7c215 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -7,8 +7,7 @@ from django.core.paginator import Page
from django.db import models
from django.forms import widgets
from django.utils.datastructures import SortedDict
-from rest_framework.compat import get_concrete_model
-from rest_framework.compat import six
+from rest_framework.compat import get_concrete_model, six
# Note: We do the following so that users of the framework can use this style:
#
@@ -285,10 +284,6 @@ class BaseSerializer(Field):
"""
Deserialize primitives -> objects.
"""
- if hasattr(data, '__iter__') and not isinstance(data, (dict, six.text_type)):
- # TODO: error data when deserializing lists
- return [self.from_native(item, None) for item in data]
-
self._errors = {}
if data is not None or files is not None:
attrs = self.restore_fields(data, files)
@@ -330,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, dict))
+ many = hasattr(obj, '__iter__') and not isinstance(obj, (Page, dict, six.text_type))
if many:
return [self.to_native(item) for item in obj]
@@ -348,19 +343,25 @@ class BaseSerializer(Field):
if self.many is not None:
many = self.many
else:
- many = hasattr(data, '__iter__') and not isinstance(data, (Page, dict))
+ many = hasattr(data, '__iter__') and not isinstance(data, (Page, dict, six.text_type))
if many:
warnings.warn('Implict list/queryset serialization is due to be deprecated. '
'Use the `many=True` flag when instantiating the serializer.',
PendingDeprecationWarning, stacklevel=3)
- # TODO: error data when deserializing lists
if many:
- ret = [self.from_native(item, None) for item in data]
- ret = self.from_native(data, files)
+ ret = []
+ errors = []
+ for item in data:
+ ret.append(self.from_native(item, None))
+ errors.append(self._errors)
+ self._errors = any(errors) and errors or []
+ else:
+ ret = self.from_native(data, files)
if not self._errors:
self.object = ret
+
return self._errors
def is_valid(self):
@@ -390,11 +391,17 @@ class BaseSerializer(Field):
return self._data
+ def save_object(self, obj):
+ obj.save()
+
def save(self):
"""
Save the deserialized object and return it.
"""
- self.object.save()
+ if isinstance(self.object, list):
+ [self.save_object(item) for item in self.object]
+ else:
+ self.save_object(self.object)
return self.object
@@ -611,11 +618,11 @@ class ModelSerializer(Serializer):
if instance:
return self.full_clean(instance)
- def save(self):
+ def save_object(self, obj):
"""
Save the deserialized object and return it.
"""
- self.object.save()
+ obj.save()
if getattr(self, 'm2m_data', None):
for accessor_name, object_list in self.m2m_data.items():
@@ -627,8 +634,6 @@ class ModelSerializer(Serializer):
setattr(self.object, accessor_name, object_list)
self.related_data = {}
- return self.object
-
class HyperlinkedModelSerializerOptions(ModelSerializerOptions):
"""