Skip to content

Commit 758b6ec

Browse files
committed
Include choices params even for non editable fields
The choices param can be usefull to populate list of possible values and to instantiate a ChoiceField on the serializer, even when field is non_editable. Relevant for the live doc and the OpenAPI integration.
1 parent 30d58a7 commit 758b6ec

2 files changed

Lines changed: 16 additions & 3 deletions

File tree

rest_framework/utils/field_mapping.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ def get_field_kwargs(field_name, model_field):
121121
if model_field.null:
122122
kwargs['allow_null'] = True
123123

124+
if model_field.choices:
125+
kwargs['choices'] = model_field.choices
126+
124127
if isinstance(model_field, models.AutoField) or not model_field.editable:
125128
# If this field is read-only, then return early.
126129
# Further keyword arguments are not valid.
@@ -151,9 +154,7 @@ def get_field_kwargs(field_name, model_field):
151154
if model_field.allow_folders is not False:
152155
kwargs['allow_folders'] = model_field.allow_folders
153156

154-
if model_field.choices:
155-
kwargs['choices'] = model_field.choices
156-
else:
157+
if not model_field.choices:
157158
# Ensure that max_value is passed explicitly as a keyword arg,
158159
# rather than as a validator.
159160
max_value = next((

tests/test_model_serializer.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
from rest_framework import serializers
2727
from rest_framework.compat import postgres_fields
28+
from rest_framework.fields import ChoiceField
2829

2930
from .models import NestedForeignKeySource
3031

@@ -95,6 +96,7 @@ class FieldOptionsModel(models.Model):
9596

9697
class ChoicesModel(models.Model):
9798
choices_field_with_nonstandard_args = models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES, verbose_name='A label')
99+
non_editable_choice_field = models.CharField(choices=COLOR_CHOICES, default=COLOR_CHOICES[0][0], editable=False)
98100

99101

100102
class Issue3674ParentModel(models.Model):
@@ -362,6 +364,16 @@ class Meta:
362364

363365
ExampleSerializer()
364366

367+
def test_non_editable_choice_field(self):
368+
class ExampleSerializer(serializers.ModelSerializer):
369+
class Meta:
370+
model = ChoicesModel
371+
fields = '__all__'
372+
373+
serializer = ExampleSerializer()
374+
non_editable_choice_field = serializer.get_fields()["non_editable_choice_field"]
375+
assert isinstance(non_editable_choice_field, ChoiceField)
376+
365377

366378
class TestDurationFieldMapping(TestCase):
367379
def test_duration_field(self):

0 commit comments

Comments
 (0)