mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 08:29:59 +03:00
Allow overriding field mappings for choice field
This commit is contained in:
parent
98e56e0327
commit
1f9f1ce6a2
|
@ -1412,13 +1412,12 @@ class ChoiceField(Field):
|
||||||
html_cutoff = None
|
html_cutoff = None
|
||||||
html_cutoff_text = _('More than {count} items...')
|
html_cutoff_text = _('More than {count} items...')
|
||||||
|
|
||||||
def __init__(self, choices, **kwargs):
|
def __init__(self, choices, allow_blank=False, **kwargs):
|
||||||
self.choices = choices
|
self.choices = choices
|
||||||
|
self.allow_blank = allow_blank
|
||||||
self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff)
|
self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff)
|
||||||
self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text)
|
self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text)
|
||||||
|
|
||||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
|
|
|
@ -1212,20 +1212,19 @@ class ModelSerializer(Serializer):
|
||||||
field_class = self.serializer_related_field
|
field_class = self.serializer_related_field
|
||||||
field_kwargs['queryset'] = model_field.related_model.objects
|
field_kwargs['queryset'] = model_field.related_model.objects
|
||||||
|
|
||||||
if 'choices' in field_kwargs:
|
if 'choices' in field_kwargs and not issubclass(field_class, self.serializer_choice_field):
|
||||||
# Fields with choices get coerced into `ChoiceField`
|
# Fields with choices get coerced into `ChoiceField`
|
||||||
# instead of using their regular typed field.
|
# instead of using their regular typed field.
|
||||||
field_class = self.serializer_choice_field
|
field_class = self.serializer_choice_field
|
||||||
# Some model fields may introduce kwargs that would not be valid
|
# Some model fields may introduce kwargs that would not be valid
|
||||||
# for the choice field. We need to strip these out.
|
# for the choice field. We need to strip these out.
|
||||||
# Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
|
# Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
|
||||||
valid_kwargs = {
|
valid_kwargs = set()
|
||||||
'read_only', 'write_only',
|
for c in inspect.getmro(field_class):
|
||||||
'required', 'default', 'initial', 'source',
|
sig = inspect.signature(c.__init__)
|
||||||
'label', 'help_text', 'style',
|
for param in sig.parameters.values():
|
||||||
'error_messages', 'validators', 'allow_null', 'allow_blank',
|
if (param.kind == param.POSITIONAL_OR_KEYWORD):
|
||||||
'choices'
|
valid_kwargs.add(param.name)
|
||||||
}
|
|
||||||
for key in list(field_kwargs):
|
for key in list(field_kwargs):
|
||||||
if key not in valid_kwargs:
|
if key not in valid_kwargs:
|
||||||
field_kwargs.pop(key)
|
field_kwargs.pop(key)
|
||||||
|
|
|
@ -217,6 +217,25 @@ class TestRegularFieldMappings(TestCase):
|
||||||
""")
|
""")
|
||||||
self.assertEqual(repr(TestSerializer()), expected)
|
self.assertEqual(repr(TestSerializer()), expected)
|
||||||
|
|
||||||
|
def test_override_choice_field_mapping(self):
|
||||||
|
class CustomChoiceField(models.CharField):
|
||||||
|
"""
|
||||||
|
A custom choice model field simply for testing purposes.
|
||||||
|
"""
|
||||||
|
max_length = 100
|
||||||
|
|
||||||
|
class CostomizedChoiceModel(models.Model):
|
||||||
|
choices_field = CustomChoiceField(choices=COLOR_CHOICES)
|
||||||
|
|
||||||
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = CostomizedChoiceModel
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
self.assertTrue(isinstance(TestSerializer().fields["choices_field"], serializers.ChoiceField))
|
||||||
|
TestSerializer.serializer_field_mapping[CustomChoiceField] = serializers.MultipleChoiceField
|
||||||
|
self.assertTrue(isinstance(TestSerializer().fields["choices_field"], serializers.MultipleChoiceField))
|
||||||
|
|
||||||
def test_nullable_boolean_field_choices(self):
|
def test_nullable_boolean_field_choices(self):
|
||||||
class NullableBooleanChoicesModel(models.Model):
|
class NullableBooleanChoicesModel(models.Model):
|
||||||
CHECKLIST_OPTIONS = (
|
CHECKLIST_OPTIONS = (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user