Skip to content

Commit 2c71a35

Browse files
epoutfranzel
andauthored
[django-filter] Add null_label if set in ChoiceFilter (#1450)
* Add null_label if set in ChoiceFilter * Fix whitespace * Replace null_label for null_value + add empty_label management * Remove empty_label --------- Co-authored-by: T. Franzel <tfranzel@users.noreply.github.com>
1 parent c014eee commit 2c71a35

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

drf_spectacular/contrib/django_filters.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,12 @@ def _get_explicit_filter_choices(self, filter_field):
228228
# choices function may utilize the DB, so refrain from actually calling it.
229229
return []
230230
else:
231-
return [c for c, _ in filter_field.extra['choices']]
231+
choices = [c for c, _ in filter_field.extra['choices']]
232+
233+
if filter_field.field.null_label:
234+
choices.append(filter_field.field.null_value)
235+
236+
return choices
232237

233238
def _get_model_field(self, filter_field, model):
234239
if not filter_field.field_name:

tests/contrib/test_django_filters.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django import __version__ as DJANGO_VERSION
55
from django.db import models
66
from django.db.models import F
7+
from django.test import override_settings
78
from django.urls import include, path
89
from rest_framework import generics, routers, serializers, viewsets
910
from rest_framework.test import APIClient
@@ -450,3 +451,31 @@ def get_queryset(self):
450451

451452
schema = generate_schema('/x/', view=XListView)
452453
assert len(schema['paths']['/x/']['get']['parameters']) > 1
454+
455+
456+
@pytest.mark.contrib('django_filter')
457+
@override_settings(
458+
FILTERS_NULL_CHOICE_VALUE="NULL VALUE",
459+
)
460+
def test_filterset_enum_includes_null_label(no_warnings):
461+
class SimpleModelFilterSet(FilterSet):
462+
class Meta:
463+
model = SimpleModel
464+
fields = ("category",)
465+
466+
category = ChoiceFilter(
467+
choices=(('a', 'A'), ('b', 'B')),
468+
null_label="NULL LABEL"
469+
)
470+
471+
class XViewSet(viewsets.ModelViewSet):
472+
queryset = SimpleModel.objects.all()
473+
serializer_class = SimpleSerializer
474+
filter_backends = [DjangoFilterBackend]
475+
filterset_class = SimpleModelFilterSet
476+
477+
schema = generate_schema('/x', XViewSet)
478+
category_type_schema = schema['paths']['/x/']['get']['parameters'][0]
479+
480+
assert category_type_schema['name'] == 'category'
481+
assert category_type_schema['schema']['enum'] == ["NULL VALUE", "a", "b"]

0 commit comments

Comments
 (0)