Skip to content

Commit caf707d

Browse files
authored
Merge pull request #1240 from intgr/fix-choicefield-with-empty-choices
Fix ChoiceField schema type with empty `choices=[]`
2 parents 304a61f + 3685aea commit caf707d

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

drf_spectacular/plumbing.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,13 @@ def build_parameter_type(
420420
def build_choice_field(field) -> _SchemaType:
421421
choices = list(OrderedDict.fromkeys(field.choices)) # preserve order and remove duplicates
422422

423-
if all(isinstance(choice, bool) for choice in choices):
424-
type: Optional[str] = 'boolean'
423+
if field.allow_blank and '' not in choices:
424+
choices.append('')
425+
426+
if not choices:
427+
type = None
428+
elif all(isinstance(choice, bool) for choice in choices):
429+
type = 'boolean'
425430
elif all(isinstance(choice, int) for choice in choices):
426431
type = 'integer'
427432
elif all(isinstance(choice, (int, float, Decimal)) for choice in choices): # `number` includes `integer`
@@ -432,8 +437,6 @@ def build_choice_field(field) -> _SchemaType:
432437
else:
433438
type = None
434439

435-
if field.allow_blank and '' not in choices:
436-
choices.append('')
437440
if field.allow_null and None not in choices:
438441
choices.append(None)
439442

tests/test_plumbing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,30 @@ def test_choicefield_choices_enum():
398398
assert schema['enum'] == ['bluepill', 'redpill', '', None]
399399
assert 'type' not in schema
400400

401+
schema = build_choice_field(serializers.ChoiceField(
402+
choices=[1, 2], allow_blank=True
403+
))
404+
assert schema['enum'] == [1, 2, '']
405+
assert 'type' not in schema
406+
407+
408+
def test_choicefield_empty_choices():
409+
schema = build_choice_field(serializers.ChoiceField(choices=[]))
410+
assert schema['enum'] == []
411+
assert 'type' not in schema
412+
413+
schema = build_choice_field(serializers.ChoiceField(choices=[], allow_null=True))
414+
assert schema['enum'] == [None]
415+
assert 'type' not in schema
416+
417+
schema = build_choice_field(serializers.ChoiceField(choices=[], allow_blank=True))
418+
assert schema['enum'] == ['']
419+
assert schema['type'] == 'string'
420+
421+
schema = build_choice_field(serializers.ChoiceField(choices=[], allow_blank=True, allow_null=True))
422+
assert schema['enum'] == ['', None]
423+
assert schema['type'] == 'string'
424+
401425

402426
def test_safe_ref():
403427
schema = build_basic_type(str)

0 commit comments

Comments
 (0)