mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 08:14:16 +03:00
Merge pull request #2239 from jpadilla/allow-blank-choicefield
Add allow_blank for ChoiceField #2184
This commit is contained in:
commit
54a18a4ddb
|
@ -958,9 +958,14 @@ class ChoiceField(Field):
|
||||||
(six.text_type(key), key) for key in self.choices.keys()
|
(six.text_type(key), key) for key in self.choices.keys()
|
||||||
])
|
])
|
||||||
|
|
||||||
|
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||||
|
|
||||||
super(ChoiceField, self).__init__(**kwargs)
|
super(ChoiceField, self).__init__(**kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
|
if data == '' and self.allow_blank:
|
||||||
|
return ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.choice_strings_to_values[six.text_type(data)]
|
return self.choice_strings_to_values[six.text_type(data)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -942,7 +942,7 @@ class ModelSerializer(Serializer):
|
||||||
# `ModelField`, which is used when no other typed field
|
# `ModelField`, which is used when no other typed field
|
||||||
# matched to the model field.
|
# matched to the model field.
|
||||||
kwargs.pop('model_field', None)
|
kwargs.pop('model_field', None)
|
||||||
if not issubclass(field_cls, CharField):
|
if not issubclass(field_cls, CharField) and not issubclass(field_cls, ChoiceField):
|
||||||
# `allow_blank` is only valid for textual fields.
|
# `allow_blank` is only valid for textual fields.
|
||||||
kwargs.pop('allow_blank', None)
|
kwargs.pop('allow_blank', None)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select class="form-control" name="{{ field.name }}">
|
<select class="form-control" name="{{ field.name }}">
|
||||||
{% if field.allow_null %}
|
{% if field.allow_null or field.allow_blank %}
|
||||||
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for key, text in field.choices.items %}
|
{% for key, text in field.choices.items %}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<label class="sr-only">{{ field.label }}</label>
|
<label class="sr-only">{{ field.label }}</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<select class="form-control" name="{{ field.name }}">
|
<select class="form-control" name="{{ field.name }}">
|
||||||
{% if field.allow_null %}
|
{% if field.allow_null or field.allow_blank %}
|
||||||
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for key, text in field.choices.items %}
|
{% for key, text in field.choices.items %}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<label {% if style.hide_label %}class="sr-only"{% endif %}>{{ field.label }}</label>
|
<label {% if style.hide_label %}class="sr-only"{% endif %}>{{ field.label }}</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<select class="form-control" name="{{ field.name }}">
|
<select class="form-control" name="{{ field.name }}">
|
||||||
{% if field.allow_null %}
|
{% if field.allow_null or field.allow_blank %}
|
||||||
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
<option value="" {% if not field.value %}selected{% endif %}>--------</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for key, text in field.choices.items %}
|
{% for key, text in field.choices.items %}
|
||||||
|
|
|
@ -91,18 +91,18 @@ def get_field_kwargs(field_name, model_field):
|
||||||
if model_field.has_default() or model_field.blank or model_field.null:
|
if model_field.has_default() or model_field.blank or model_field.null:
|
||||||
kwargs['required'] = False
|
kwargs['required'] = False
|
||||||
|
|
||||||
if model_field.flatchoices:
|
|
||||||
# If this model field contains choices, then return early.
|
|
||||||
# Further keyword arguments are not valid.
|
|
||||||
kwargs['choices'] = model_field.flatchoices
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
if model_field.null and not isinstance(model_field, models.NullBooleanField):
|
if model_field.null and not isinstance(model_field, models.NullBooleanField):
|
||||||
kwargs['allow_null'] = True
|
kwargs['allow_null'] = True
|
||||||
|
|
||||||
if model_field.blank:
|
if model_field.blank:
|
||||||
kwargs['allow_blank'] = True
|
kwargs['allow_blank'] = True
|
||||||
|
|
||||||
|
if model_field.flatchoices:
|
||||||
|
# If this model field contains choices, then return early.
|
||||||
|
# Further keyword arguments are not valid.
|
||||||
|
kwargs['choices'] = model_field.flatchoices
|
||||||
|
return kwargs
|
||||||
|
|
||||||
# Ensure that max_length is passed explicitly as a keyword arg,
|
# Ensure that max_length is passed explicitly as a keyword arg,
|
||||||
# rather than as a validator.
|
# rather than as a validator.
|
||||||
max_length = getattr(model_field, 'max_length', None)
|
max_length = getattr(model_field, 'max_length', None)
|
||||||
|
|
|
@ -804,6 +804,21 @@ class TestChoiceField(FieldValues):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_allow_blank(self):
|
||||||
|
"""
|
||||||
|
If `allow_blank=True` then '' is a valid input.
|
||||||
|
"""
|
||||||
|
field = serializers.ChoiceField(
|
||||||
|
allow_blank=True,
|
||||||
|
choices=[
|
||||||
|
('poor', 'Poor quality'),
|
||||||
|
('medium', 'Medium quality'),
|
||||||
|
('good', 'Good quality'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
output = field.run_validation('')
|
||||||
|
assert output is ''
|
||||||
|
|
||||||
|
|
||||||
class TestChoiceFieldWithType(FieldValues):
|
class TestChoiceFieldWithType(FieldValues):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user