Search code examples
pythondjangodjango-filter

How to use django-filter with a ListView class view for search?


I have a filter:

class BookFilter(django_filters.FilterSet):

    class Meta:
        model = Book
        fields = '__all__'

and a ListView to see the results:

class SearchResultsListView(ListView):
    model = Book
    context_object_name = 'book_list'
    template_name = 'book/search_results.html'

I want to have a search form where you can filter based on all fields of a class (ex, all books written by X with more than 3 stars).

How do I pass the form to the model, and how do I use the get request to filter with django-filter as needed?

I'm using Django 3.0 and django-filter 2.2.0


Solution

  • I think everything is well documented in the django-filter documentation under Generic view & configuration section.

    The django_filters.views.FilterView class is similar to Django's ListView and you can use it to filter the results.

    from django_filters.views import FilterView
    
    
    class SearchResultsListView(FilterView):
        model = Book
        context_object_name = 'book_list'
        template_name = 'book/search_results.html'
        filterset_class = BookFilter # ADD YOUR filterset class
    

    and do some change in your book/search_results.html template as mentioned in here,

    {% extends "base.html" %}
    
    {% block content %}
        <form action="" method="get">
            {{ filter.form.as_p }}
            <input type="submit" />
        </form>
        {% for obj in filter.qs %}
            {{ obj.name }} - ${{ obj.price }}<br />
        {% endfor %}
    {% endblock %}
    

    Key Points

    1. Update SearchResultsListView class by inheriting FilterView class
    2. Add filterset_class attribute to your SearchResultsListView view class
    3. The FilterView class automatically adding the filterset_class class in the get_context_data(...) method to filter key, which can be accessible later in the template.
    4. Use filter.qs in your template to get filtered queryset