From 26f9acb45ac0dcd1363399f518834c56d3f9984d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 4 Jan 2013 14:11:05 +0000 Subject: [PATCH] Validation errors instead of exceptions when serializers receive incorrect types. Fixes #402. --- docs/topics/release-notes.md | 1 + rest_framework/serializers.py | 7 ++++++- rest_framework/tests/serializer.py | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 40b65761e..eff7314b8 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -18,6 +18,7 @@ Major version numbers (x.0.0) are reserved for project milestones. No major poi ### Master +* Bugfix: Validation errors instead of exceptions when serializers receive incorrect types. * Bugfix: Validation errors instead of exceptions when related fields receive incorrect types. ### 2.1.15 diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index bd54db4ca..fa92838b6 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -208,6 +208,11 @@ class BaseSerializer(Field): Converts a dictionary of data into a dictionary of deserialized fields. """ 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(): field.initialize(parent=self, field_name=field_name) try: @@ -276,7 +281,7 @@ 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) + return [self.from_native(item, None) for item in data] self._errors = {} if data is not None or files is not None: diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 8767385eb..bd96ba23e 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -69,6 +69,7 @@ class AlbumsSerializer(serializers.ModelSerializer): model = Album fields = ['title'] # lists are also valid options + class PositiveIntegerAsChoiceSerializer(serializers.ModelSerializer): class Meta: model = HasPositiveIntegerAsChoice @@ -240,6 +241,25 @@ class ValidationTests(TestCase): self.assertFalse(serializer.is_valid()) 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): class CommentSerializerWithCrossFieldValidator(CommentSerializer):