Skip to content

Fix support for ListField default values in HTML mode #5812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,9 @@ def get_value(self, dictionary):
# We override the default field access in order to support
# lists in HTML forms.
if html.is_html_input(dictionary):
if self.field_name not in dictionary:
if not any(k.startswith("%s[" % self.field_name) for k in dictionary):
Copy link
Author

@awbacker awbacker Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this support alternate field separators, such as field.0?

return empty
val = dictionary.getlist(self.field_name, [])
if len(val) > 0:
# Support QueryDict lists in HTML input.
Expand Down
50 changes: 50 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,56 @@ class TestSerializer(serializers.Serializer):
assert serializer.is_valid()
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_supports_indexed_keys(self):
"""
When data is passed in the format `scores[0]=1&scores[1]=3`
The field should return the correct list, ignoring the default
"""
class TestSerializer(serializers.Serializer):
scores = serializers.ListField(default=lambda: [1, 3])

serializer = TestSerializer(data=QueryDict("scores[0]=5&scores[1]=6"))
assert serializer.is_valid()
assert serializer.validated_data == {'scores': ['5', '6']}

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 == {}

def test_querydict_list_input_posts_key_but_no_values(self):
"""
When there are no keys passed, there is no default, and required=False
The field should return an array of 1 item, blank
* Not sure if this is desired behavior, but it is logical at least
"""
class TestSerializer(serializers.Serializer):
scores = serializers.ListField(required=False)

serializer = TestSerializer(data=QueryDict('scores=&'))
assert serializer.is_valid()
assert serializer.validated_data == {'scores': ['']}


class TestCreateOnlyDefault:
def setup(self):
Expand Down
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