[Django]-How to display empty_label for non-mandatory fields with django-filter?

6👍

First of all, you should not add the blank choice to your choices set. So please remove the following lines:

('','---------'),

Django will automatically add these when the Field is not required and everything (django models, django forms, django views etc) except django-filter will work as expected.

Now, concerning django-filter. What you describe is a common requirement, already present in the issues of the django-filter project. Please take a look here for a possible workaround https://github.com/alex/django-filter/issues/45. I will just copy paste cvk77’s code from there for reference:

class NicerFilterSet(django_filters.FilterSet):

def __init__(self, *args, **kwargs):
  super(NicerFilterSet, self).__init__(*args, **kwargs)

  for name, field in self.filters.iteritems():
    if isinstance(field, ChoiceFilter):
      # Add "Any" entry to choice fields.
      field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))`

So to use that just extend your filters from NicerFilterSet instead of normal FilterSet.

Also a Q+D solution you could do is the following: Define a global variable in your models.py:

GENDER_CHOICES = (
  ('Male','Male'),
  ('Female','Female'),
)

and use it as expected in your Model.

Now, in your filters.py define another global variable like this:

FILTER_GENDER_CHOICES = list(models.FILTER_CHOICES)
FILTER_GENDER_CHOICES.insert(0, ('','---------') )

and then define your filter like this:

class ShopperFilter(django_filters.FilterSet):
  gender = django_filters.ChoiceFilter(choices= FILTER_GENDER_CHOICES ) 
  class Meta:
    model = models.Shopper

0👍

For the less experienced, here’s a Python3 compatible version of the original work-around by cvk77, which I found in the accepted answer by @Serafeim.

class NicerFilterSet(django_filters.FilterSet):

def __init__(self, *args, **kwargs):
  super(NicerFilterSet, self).__init__(*args, **kwargs)

  for name, field in self.filters.items():
    if isinstance(field, ChoiceFilter):
      # Add "Any" entry to choice fields.
      field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))

Changes:

  • self.filters.iteritems() was changed to self.filters.items()
  • Remove erroneous backtick (it was present in the github thread too – no fault of @Serafeim)

Leave a comment