Skip to content

Commit f2c6551

Browse files
committed
Merge pull request #3415 from adamsc64/issue_2761
Fixed #2761 - ListField truncation on HTTP PATCH
2 parents b1a5294 + 9ccfc94 commit f2c6551

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

rest_framework/fields.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1265,14 +1265,13 @@ def __init__(self, *args, **kwargs):
12651265
super(MultipleChoiceField, self).__init__(*args, **kwargs)
12661266

12671267
def get_value(self, dictionary):
1268+
if self.field_name not in dictionary:
1269+
if getattr(self.root, 'partial', False):
1270+
return empty
12681271
# We override the default field access in order to support
12691272
# lists in HTML forms.
12701273
if html.is_html_input(dictionary):
1271-
ret = dictionary.getlist(self.field_name)
1272-
if getattr(self.root, 'partial', False) and not ret:
1273-
ret = empty
1274-
return ret
1275-
1274+
return dictionary.getlist(self.field_name)
12761275
return dictionary.get(self.field_name, empty)
12771276

12781277
def to_internal_value(self, data):
@@ -1419,6 +1418,9 @@ def __init__(self, *args, **kwargs):
14191418
self.child.bind(field_name='', parent=self)
14201419

14211420
def get_value(self, dictionary):
1421+
if self.field_name not in dictionary:
1422+
if getattr(self.root, 'partial', False):
1423+
return empty
14221424
# We override the default field access in order to support
14231425
# lists in HTML forms.
14241426
if html.is_html_input(dictionary):

tests/test_serializer_lists.py

+29
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,32 @@ class Meta:
289289
serializer = TestSerializer(data=[], many=True)
290290
assert not serializer.is_valid()
291291
assert serializer.errors == {'non_field_errors': ['Non field error']}
292+
293+
294+
class TestSerializerPartialUsage:
295+
"""
296+
When not submitting key for list fields or multiple choice, partial
297+
serialization should result in an empty state (key not there), not
298+
an empty list.
299+
300+
Regression test for Github issue #2761.
301+
"""
302+
def test_partial_listfield(self):
303+
class ListSerializer(serializers.Serializer):
304+
listdata = serializers.ListField()
305+
serializer = ListSerializer(data=MultiValueDict(), partial=True)
306+
result = serializer.to_internal_value(data={})
307+
assert "listdata" not in result
308+
assert serializer.is_valid()
309+
assert serializer.validated_data == {}
310+
assert serializer.errors == {}
311+
312+
def test_partial_multiplechoice(self):
313+
class MultipleChoiceSerializer(serializers.Serializer):
314+
multiplechoice = serializers.MultipleChoiceField(choices=[1, 2, 3])
315+
serializer = MultipleChoiceSerializer(data=MultiValueDict(), partial=True)
316+
result = serializer.to_internal_value(data={})
317+
assert "multiplechoice" not in result
318+
assert serializer.is_valid()
319+
assert serializer.validated_data == {}
320+
assert serializer.errors == {}

0 commit comments

Comments
 (0)