mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-23 15:54:16 +03:00
Errors during deserializing lists now return a list of tuples with
index of bad item in data plus usual errors dict
This commit is contained in:
parent
4e80541824
commit
66605acaf0
|
@ -93,6 +93,8 @@ To serialize a queryset instead of an object instance, you should pass the `many
|
|||
|
||||
When deserializing data, you always need to call `is_valid()` before attempting to access the deserialized object. If any validation errors occur, the `.errors` and `.non_field_errors` properties will contain the resulting error messages.
|
||||
|
||||
When deserialising a list of items, errors will be returned as a list of tuples. The first item in an error tuple will be the index of the item with the error in the original data; The second item in the tuple will be a dict with the individual errors for that item.
|
||||
|
||||
### Field-level validation
|
||||
|
||||
You can specify custom field-level validation by adding `.validate_<fieldname>` methods to your `Serializer` subclass. These are analagous to `.clean_<fieldname>` methods on Django forms, but accept slightly different arguments.
|
||||
|
|
|
@ -286,8 +286,18 @@ 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]
|
||||
object_list = list()
|
||||
error_list = list()
|
||||
for count, item in enumerate(data):
|
||||
obj = self.from_native(item, None)
|
||||
if self._errors:
|
||||
error_list.append((count, self._errors))
|
||||
object_list.append(obj)
|
||||
if not error_list:
|
||||
return object_list
|
||||
|
||||
self._errors = error_list
|
||||
return None
|
||||
|
||||
self._errors = {}
|
||||
if data is not None or files is not None:
|
||||
|
@ -354,9 +364,6 @@ class BaseSerializer(Field):
|
|||
'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)
|
||||
|
||||
if not self._errors:
|
||||
|
|
|
@ -268,7 +268,16 @@ class ValidationTests(TestCase):
|
|||
data = ['i am', 'a', 'list']
|
||||
serializer = CommentSerializer(self.comment, data=data, many=True)
|
||||
self.assertEqual(serializer.is_valid(), False)
|
||||
self.assertEqual(serializer.errors, {'non_field_errors': ['Invalid data']})
|
||||
self.assertTrue(isinstance(serializer.errors, list))
|
||||
|
||||
self.assertEqual(
|
||||
serializer.errors,
|
||||
[
|
||||
(0, {'non_field_errors': ['Invalid data']}),
|
||||
(1, {'non_field_errors': ['Invalid data']}),
|
||||
(2, {'non_field_errors': ['Invalid data']})
|
||||
]
|
||||
)
|
||||
|
||||
data = 'and i am a string'
|
||||
serializer = CommentSerializer(self.comment, data=data)
|
||||
|
@ -1072,3 +1081,37 @@ 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 DeserializeListTestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.data = {
|
||||
'email': 'nobody@nowhere.com',
|
||||
'content': 'This is some test content',
|
||||
'created': datetime.datetime(2013, 3, 7),
|
||||
}
|
||||
|
||||
def test_no_errors(self):
|
||||
data = [self.data.copy() for x in range(0, 3)]
|
||||
serializer = CommentSerializer(data=data)
|
||||
self.assertTrue(serializer.is_valid())
|
||||
self.assertTrue(isinstance(serializer.object, list))
|
||||
self.assertTrue(
|
||||
all((isinstance(item, Comment) for item in serializer.object))
|
||||
)
|
||||
|
||||
def test_errors_return_as_list(self):
|
||||
invalid_item = self.data.copy()
|
||||
invalid_item['email'] = ''
|
||||
data = [self.data.copy(), invalid_item, self.data.copy()]
|
||||
|
||||
serializer = CommentSerializer(data=data)
|
||||
self.assertFalse(serializer.is_valid())
|
||||
self.assertTrue(isinstance(serializer.errors, list))
|
||||
self.assertEqual(1, len(serializer.errors))
|
||||
expected = (1, {'email': ['This field is required.']})
|
||||
self.assertEqual(
|
||||
serializer.errors[0],
|
||||
expected
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user