Skip to content

Commit 3242adf

Browse files
reupentomchristie
authored andcommitted
Enforce allow_empty=False during partial validation of parent serializer (#6512)
Refs #6509 This enforces allow_empty=True when a ListSerializer is a child of another serializer and partial validation is being performed on the parent serializer. This is because partial validation should allow fields to be omitted, but should not cause values that are invalid without partial validation to become valid. This effectively reverts #4222. None of the tests added in that PR fail if the associated change is removed, so I‘m not sure what that PR was trying to fix.
1 parent 79b2350 commit 3242adf

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

rest_framework/serializers.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -590,10 +590,6 @@ def __init__(self, *args, **kwargs):
590590
super().__init__(*args, **kwargs)
591591
self.child.bind(field_name='', parent=self)
592592

593-
def bind(self, field_name, parent):
594-
super().bind(field_name, parent)
595-
self.partial = self.parent.partial
596-
597593
def get_initial(self):
598594
if hasattr(self, 'initial_data'):
599595
return self.to_representation(self.initial_data)
@@ -645,9 +641,6 @@ def to_internal_value(self, data):
645641
}, code='not_a_list')
646642

647643
if not self.allow_empty and len(data) == 0:
648-
if self.parent and self.partial:
649-
raise SkipField()
650-
651644
message = self.error_messages['empty']
652645
raise ValidationError({
653646
api_settings.NON_FIELD_ERRORS_KEY: [message]

tests/test_serializer_lists.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import pytest
12
from django.http import QueryDict
23
from django.utils.datastructures import MultiValueDict
34

45
from rest_framework import serializers
6+
from rest_framework.exceptions import ErrorDetail
57

68

79
class BasicObject:
@@ -223,6 +225,49 @@ def test_validate_html_input(self):
223225
assert serializer.validated_data == expected_output
224226

225227

228+
class TestNestedListSerializerAllowEmpty:
229+
"""Tests the behaviour of allow_empty=False when a ListSerializer is used as a field."""
230+
231+
@pytest.mark.parametrize('partial', (False, True))
232+
def test_allow_empty_true(self, partial):
233+
"""
234+
If allow_empty is True, empty lists should be allowed regardless of the value
235+
of partial on the parent serializer.
236+
"""
237+
class ChildSerializer(serializers.Serializer):
238+
id = serializers.IntegerField()
239+
240+
class ParentSerializer(serializers.Serializer):
241+
ids = ChildSerializer(many=True, allow_empty=True)
242+
243+
serializer = ParentSerializer(data={'ids': []}, partial=partial)
244+
assert serializer.is_valid()
245+
assert serializer.validated_data == {
246+
'ids': [],
247+
}
248+
249+
@pytest.mark.parametrize('partial', (False, True))
250+
def test_allow_empty_false(self, partial):
251+
"""
252+
If allow_empty is False, empty lists should fail validation regardless of the value
253+
of partial on the parent serializer.
254+
"""
255+
class ChildSerializer(serializers.Serializer):
256+
id = serializers.IntegerField()
257+
258+
class ParentSerializer(serializers.Serializer):
259+
ids = ChildSerializer(many=True, allow_empty=False)
260+
261+
serializer = ParentSerializer(data={'ids': []}, partial=partial)
262+
assert not serializer.is_valid()
263+
assert serializer.errors == {
264+
'ids': {
265+
'non_field_errors': [
266+
ErrorDetail(string='This list may not be empty.', code='empty')],
267+
}
268+
}
269+
270+
226271
class TestNestedListOfListsSerializer:
227272
def setup(self):
228273
class TestSerializer(serializers.Serializer):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy