Commit 26f9acb4 by Tom Christie

Validation errors instead of exceptions when serializers receive incorrect types. Fixes #402.

parent eb14278a
...@@ -18,6 +18,7 @@ Major version numbers (x.0.0) are reserved for project milestones. No major poi ...@@ -18,6 +18,7 @@ Major version numbers (x.0.0) are reserved for project milestones. No major poi
### Master ### Master
* Bugfix: Validation errors instead of exceptions when serializers receive incorrect types.
* Bugfix: Validation errors instead of exceptions when related fields receive incorrect types. * Bugfix: Validation errors instead of exceptions when related fields receive incorrect types.
### 2.1.15 ### 2.1.15
......
...@@ -208,6 +208,11 @@ class BaseSerializer(Field): ...@@ -208,6 +208,11 @@ class BaseSerializer(Field):
Converts a dictionary of data into a dictionary of deserialized fields. Converts a dictionary of data into a dictionary of deserialized fields.
""" """
reverted_data = {} reverted_data = {}
if data is not None and not isinstance(data, dict):
self._errors['non_field_errors'] = [u'Invalid data']
return None
for field_name, field in self.fields.items(): for field_name, field in self.fields.items():
field.initialize(parent=self, field_name=field_name) field.initialize(parent=self, field_name=field_name)
try: try:
...@@ -276,7 +281,7 @@ class BaseSerializer(Field): ...@@ -276,7 +281,7 @@ class BaseSerializer(Field):
""" """
if hasattr(data, '__iter__') and not isinstance(data, dict): if hasattr(data, '__iter__') and not isinstance(data, dict):
# TODO: error data when deserializing lists # TODO: error data when deserializing lists
return (self.from_native(item) for item in data) return [self.from_native(item, None) for item in data]
self._errors = {} self._errors = {}
if data is not None or files is not None: if data is not None or files is not None:
......
...@@ -69,6 +69,7 @@ class AlbumsSerializer(serializers.ModelSerializer): ...@@ -69,6 +69,7 @@ class AlbumsSerializer(serializers.ModelSerializer):
model = Album model = Album
fields = ['title'] # lists are also valid options fields = ['title'] # lists are also valid options
class PositiveIntegerAsChoiceSerializer(serializers.ModelSerializer): class PositiveIntegerAsChoiceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = HasPositiveIntegerAsChoice model = HasPositiveIntegerAsChoice
...@@ -240,6 +241,25 @@ class ValidationTests(TestCase): ...@@ -240,6 +241,25 @@ class ValidationTests(TestCase):
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'content': [u'Test not in value']}) self.assertEquals(serializer.errors, {'content': [u'Test not in value']})
def test_bad_type_data_is_false(self):
"""
Data of the wrong type is not valid.
"""
data = ['i am', 'a', 'list']
serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']})
data = 'and i am a string'
serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']})
data = 42
serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']})
def test_cross_field_validation(self): def test_cross_field_validation(self):
class CommentSerializerWithCrossFieldValidator(CommentSerializer): class CommentSerializerWithCrossFieldValidator(CommentSerializer):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment