mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-29 13:04:03 +03:00
Fix for ModelSerializer ChoiceField with nonstandard args. Closes #3126.
This commit is contained in:
parent
713333d354
commit
e14391e041
|
@ -1033,6 +1033,19 @@ class ModelSerializer(Serializer):
|
||||||
# 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
|
||||||
|
# for the choice field. We need to strip these out.
|
||||||
|
# Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
|
||||||
|
valid_kwargs = set((
|
||||||
|
'read_only', 'write_only',
|
||||||
|
'required', 'default', 'initial', 'source',
|
||||||
|
'label', 'help_text', 'style',
|
||||||
|
'error_messages', 'validators', 'allow_null', 'allow_blank',
|
||||||
|
'choices'
|
||||||
|
))
|
||||||
|
for key in list(field_kwargs.keys()):
|
||||||
|
if key not in valid_kwargs:
|
||||||
|
field_kwargs.pop(key)
|
||||||
|
|
||||||
if not issubclass(field_class, ModelField):
|
if not issubclass(field_class, ModelField):
|
||||||
# `model_field` is only valid for the fallback case of
|
# `model_field` is only valid for the fallback case of
|
||||||
|
|
|
@ -7,6 +7,8 @@ an appropriate set of serializer fields for each case.
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import decimal
|
||||||
|
|
||||||
import django
|
import django
|
||||||
import pytest
|
import pytest
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
@ -70,6 +72,7 @@ class RegularFieldsModel(models.Model):
|
||||||
|
|
||||||
|
|
||||||
COLOR_CHOICES = (('red', 'Red'), ('blue', 'Blue'), ('green', 'Green'))
|
COLOR_CHOICES = (('red', 'Red'), ('blue', 'Blue'), ('green', 'Green'))
|
||||||
|
DECIMAL_CHOICES = (('low', decimal.Decimal('0.1')), ('medium', decimal.Decimal('0.5')), ('high', decimal.Decimal('0.9')))
|
||||||
|
|
||||||
|
|
||||||
class FieldOptionsModel(models.Model):
|
class FieldOptionsModel(models.Model):
|
||||||
|
@ -82,6 +85,10 @@ class FieldOptionsModel(models.Model):
|
||||||
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES)
|
choices_field = models.CharField(max_length=100, choices=COLOR_CHOICES)
|
||||||
|
|
||||||
|
|
||||||
|
class MappingForChoicesWithNonStandardArgs(models.Model):
|
||||||
|
choices_field_with_nonstandard_args = models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES)
|
||||||
|
|
||||||
|
|
||||||
class TestModelSerializer(TestCase):
|
class TestModelSerializer(TestCase):
|
||||||
def test_create_method(self):
|
def test_create_method(self):
|
||||||
class TestSerializer(serializers.ModelSerializer):
|
class TestSerializer(serializers.ModelSerializer):
|
||||||
|
@ -307,6 +314,13 @@ class TestRegularFieldMappings(TestCase):
|
||||||
|
|
||||||
ChildSerializer().fields
|
ChildSerializer().fields
|
||||||
|
|
||||||
|
def test_choices_with_nonstandard_args(self):
|
||||||
|
class ExampleSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = MappingForChoicesWithNonStandardArgs
|
||||||
|
|
||||||
|
ExampleSerializer()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(django.VERSION < (1, 8),
|
@pytest.mark.skipif(django.VERSION < (1, 8),
|
||||||
reason='DurationField is only available for django1.8+')
|
reason='DurationField is only available for django1.8+')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user