djangofilterdjango-filter

Django-filters: Displaying a list of choices for filtering a TextField


In my django based web application I have a model which is defined as following in models.py:

class Machine(models.Model):
  ip_address = models.TextField(blank=False, unique=True)
  hostname = models.TextField(blank=False, unique=True)

In my filters.py file I would like to create a filter based on the ip_address field where the user will select the IP from a list of choices. I defined it as following:

class MachineFilter(django_filters.FilterSet):
    ip_address = ModelChoiceFilter(queryset=Machine.objects.all().values_list('ip_address', flat=True))    

class Meta:
    model = Machine
    fields = ['ip_address', 'hostname']

However, when selecting the desired IP in the web form I get the following error:

Ip address: Select a valid choice. That choice is not one of the available choices.

I tried removing the flat=True from the value list definition but this still did not work.

What am I doing wrong?


Solution

  • This is not a ModelChoiceFilter, but a ChoiceField. A ModelChoiceFilter means you are select a model, but here you select an IP address, you thus should use a ChoiceField:

    class MachineFilter(django_filters.FilterSet):
        ip_address = ChoiceFilter(choices=[])
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.filters['ip_address'].extra['choices'] = [
                (ip, ip)
                for ip in Machine.objects.values_list('ip_address', flat=True)
            ]
    
        class Meta:
            model = Machine
            fields = ['ip_address', 'hostname']