11

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

1 Answer 1

15
+100

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
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much, I just needed a full example. Just to make sure, I don't need a csrf_token in the form?
csrf_token is something to do with HTTP POST requests and the filter usually works with HTTP GET. So, in your case, we don't need it
Thanks for the addditional Key Points, very useful!
One can also lookup the template using the book_list as it is declared as context_object_name. In this case you don't have to refactor your template with filter.qs. It is better to user filter.form for rendering the filtering form and book_list to render the data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.