Fix support for ListField default values in HTML mode

The ListField handles html forms data differently than json data.  This section
would always return a value (an empty list) for a list field, even when that
field name was not posted at all.  This change checks for the field being
present and returns `empty` if it is not; this lets the standard default-value and
required field handling take over.
This commit is contained in:
Andrew Backer 2018-02-07 12:45:33 +08:00
parent c456b3c510
commit 55f6427ef4
2 changed files with 27 additions and 0 deletions

View File

@ -1609,6 +1609,8 @@ class ListField(Field):
# We override the default field access in order to support # We override the default field access in order to support
# lists in HTML forms. # lists in HTML forms.
if html.is_html_input(dictionary): if html.is_html_input(dictionary):
if self.field_name not in dictionary:
return empty
val = dictionary.getlist(self.field_name, []) val = dictionary.getlist(self.field_name, [])
if len(val) > 0: if len(val) > 0:
# Support QueryDict lists in HTML input. # Support QueryDict lists in HTML input.

View File

@ -459,6 +459,31 @@ class TestHTMLInput:
assert serializer.is_valid() assert serializer.is_valid()
assert serializer.validated_data == {'scores': [1]} assert serializer.validated_data == {'scores': [1]}
def test_querydict_list_input_no_values_uses_default(self):
"""
When there are no values passed in, and default is set
The field should return the default value
"""
class TestSerializer(serializers.Serializer):
a = serializers.IntegerField(required=True)
scores = serializers.ListField(default=lambda: [1, 3])
serializer = TestSerializer(data=QueryDict('a=1&'))
assert serializer.is_valid()
assert serializer.validated_data == {'a': 1, 'scores': [1, 3]}
def test_querydict_list_input_no_values_no_default_and_not_required(self):
"""
When there are no keys passed, there is no default, and required=False
The field should be skipped
"""
class TestSerializer(serializers.Serializer):
scores = serializers.ListField(required=False)
serializer = TestSerializer(data=QueryDict(''))
assert serializer.is_valid()
assert serializer.validated_data == {}
class TestCreateOnlyDefault: class TestCreateOnlyDefault:
def setup(self): def setup(self):