diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index c7d4405c59..037939e318 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -113,8 +113,13 @@ def many_init(cls, *args, **kwargs): kwargs['child'] = cls() return CustomListSerializer(*args, **kwargs) """ + allow_empty = kwargs.pop('allow_empty', None) child_serializer = cls(*args, **kwargs) - list_kwargs = {'child': child_serializer} + list_kwargs = { + 'child': child_serializer, + } + if allow_empty is not None: + list_kwargs['allow_empty'] = allow_empty list_kwargs.update(dict([ (key, value) for key, value in kwargs.items() if key in LIST_SERIALIZER_KWARGS diff --git a/tests/test_serializer_nested.py b/tests/test_serializer_nested.py index 22d4deca15..aeb092ee05 100644 --- a/tests/test_serializer_nested.py +++ b/tests/test_serializer_nested.py @@ -79,17 +79,23 @@ class NestedSerializer(serializers.Serializer): class TestSerializer(serializers.Serializer): allow_null = NestedSerializer(many=True, allow_null=True) not_allow_null = NestedSerializer(many=True) + allow_empty = NestedSerializer(many=True, allow_empty=True) + not_allow_empty = NestedSerializer(many=True, allow_empty=False) self.Serializer = TestSerializer def test_null_allowed_if_allow_null_is_set(self): input_data = { 'allow_null': None, - 'not_allow_null': [{'example': '2'}, {'example': '3'}] + 'not_allow_null': [{'example': '2'}, {'example': '3'}], + 'allow_empty': [{'example': '2'}], + 'not_allow_empty': [{'example': '2'}], } expected_data = { 'allow_null': None, - 'not_allow_null': [{'example': 2}, {'example': 3}] + 'not_allow_null': [{'example': 2}, {'example': 3}], + 'allow_empty': [{'example': 2}], + 'not_allow_empty': [{'example': 2}], } serializer = self.Serializer(data=input_data) @@ -99,7 +105,9 @@ def test_null_allowed_if_allow_null_is_set(self): def test_null_is_not_allowed_if_allow_null_is_not_set(self): input_data = { 'allow_null': None, - 'not_allow_null': None + 'not_allow_null': None, + 'allow_empty': [{'example': '2'}], + 'not_allow_empty': [{'example': '2'}], } serializer = self.Serializer(data=input_data) @@ -118,10 +126,44 @@ def validate_allow_null(self, value): input_data = { 'allow_null': None, - 'not_allow_null': [{'example': 2}] + 'not_allow_null': [{'example': 2}], + 'allow_empty': [{'example': 2}], + 'not_allow_empty': [{'example': 2}], } serializer = TestSerializer(data=input_data) assert serializer.is_valid() assert serializer.validated_data == input_data assert TestSerializer.validation_was_run + + def test_empty_allowed_if_allow_empty_is_set(self): + input_data = { + 'allow_null': [{'example': '2'}], + 'not_allow_null': [{'example': '2'}], + 'allow_empty': [], + 'not_allow_empty': [{'example': '2'}], + } + expected_data = { + 'allow_null': [{'example': 2}], + 'not_allow_null': [{'example': 2}], + 'allow_empty': [], + 'not_allow_empty': [{'example': 2}], + } + serializer = self.Serializer(data=input_data) + + assert serializer.is_valid(), serializer.errors + assert serializer.validated_data == expected_data + + def test_empty_not_allowed_if_allow_empty_is_set_to_false(self): + input_data = { + 'allow_null': [{'example': '2'}], + 'not_allow_null': [{'example': '2'}], + 'allow_empty': [], + 'not_allow_empty': [], + } + serializer = self.Serializer(data=input_data) + + assert not serializer.is_valid() + + expected_errors = {'not_allow_empty': {'non_field_errors': [serializers.ListSerializer.default_error_messages['empty']]}} + assert serializer.errors == expected_errors