mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-26 05:31:07 +03:00 
			
		
		
		
	Merge branch 'master' of https://github.com/bitmonkey/django-rest-framework into list-deserialization
This commit is contained in:
		
						commit
						53b58a5059
					
				|  | @ -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