user8954282
user8954282

Reputation:

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

Upvotes: 11

Views: 8942

Answers (1)

JPG
JPG

Reputation: 88459

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

Upvotes: 15

Related Questions