I'm using Django-filter, and I would like one of the fields (supervisor
) to be a ChoiceFilter
where the choices are objects from the model. What's the most efficient way to do that? I tried following this post, but kept getting errors no matter what I changed (currently cannot unpack non-iterable int object
).
# models.py
class people(models.Model):
namelast = models.CharField(max_length=100, verbose_name='Last Name')
namefirst = models.CharField(max_length=100, verbose_name='First Name')
supervisor = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL, verbose_name='Supervisor')
def __str__(self):
return "%s %s" % (self.namefirst, self.namelast)
# filters.py
class office_filter(django_filters.FilterSet):
supervisor = django_filters.ChoiceFilter(choices=[], lookup_expr='icontains', label='Supervisor')
# other fields
class Meta:
model = people
fields = ['namelast', 'namefirst', 'supervisor']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
try:
self.filters['supervisor'].extra['choices'] = [x for x in
people.objects.all().values_list('supervisor', flat=True).distinct()]
except (KeyError, AttributeError):
pass
The goal is to have the supervisor
field be a nice menu of all of the people that have been added assigned as a supervisor in the people
model.
Ananya's answer helped me get on the correct track of what have that statement return, but after thinking about the errors and how choice lists are usually constructed, I realized I needed it to return a tuple (not just a value). Here is the relevant code that ended up working:
class office_filter(django_filters.FilterSet):
supervisor = django_filters.ChoiceFilter(choices=[], label='Supervisor')
#...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
try:
self.filters['supervisor'].extra['choices'] = [(people.objects.get(pk=x).id, people.objects.get(pk=x)) for x in people.objects.all().values_list('supervisor', flat=True).distinct() if x is not None]
except (KeyError, AttributeError):
pass
The important part being: (people.objects.get(pk=x).id, people.objects.get(pk=x))
rather than just people.objects.get(pk=x)
.
Also had to remove lookup_expr
in the filter field.