Search code examples
pythondjangodjango-filter

Django_filters - MultipleChoiceFilter with ForeignKey not shown


I'm trying to filter a digital product with multiple filters. On of them includes the functionality model. So the user select a category and then, related to the category, can filter the existing products by their functionality models.py

class Platform(models.Model):
    name = models.CharField(max_length=200, verbose_name='Name')
    thumbnail = models.ImageField(upload_to='DigitalProduct/thumbnails')
    category = models.ForeignKey(Category, on_delete=models.CASCADE)


class Category(models.Model):
    category = models.CharField(max_length=200)
    filter_functions = models.ManyToManyField(Functionality, verbose_name='Filter by')


class Functionality(models.Model):
    functionality = models.CharField(max_length=200)

I installed django-filter v2.4.0 and trying to add the filters. filters.py

...
class PlatformFilter(django_filters.FilterSet):
    func = django_filters.MultipleChoiceFilter(field_name='category', conjoined=True)

Inside of my views.py function I pass the queryset=Platform.objects.filter(category=category) to get the correct digital products, which is working fine but the category values aren't shown in the MultipleChoiceField.

views.py

def platform_list(request, slug):
    category = Category.objects.get(slug=slug)
    # filter query
    f = PlatformFilter(request.GET, queryset=Platform.objects.filter(category=category))
    return render(request, 'core/platform-list.html', {
        'category': category,
        'filter': f
    })

So far I can see the MultipleChoiceField but no values are shown. image example

I tried to change the field name to field_name='category.category' but I get an [invalid name].

Do I miss something?


Solution

  • Normally if one would want to use a MultipleChoiceFilter they would have to provide the choices which you don't hence no choices are displayed.

    Furthermore since category is a ForeignKey then instead of using a MultipleChoiceFilter you should be using a ModelMultipleChoiceFilter [django-filter docs] instead:

    class PlatformFilter(django_filters.FilterSet):
        func = django_filters.ModelMultipleChoiceFilter(field_name='category', queryset=Category.objects.all(), conjoined=True)