Filtering QuerySets dynamically is a fairly common use case. Sure thing there is a pluggable app to make your life
easier. This tutorial is about how to use the django-filter app to add a hassle-free filtering to your views.
To illustrate this tutorial I will implement a view to search for users. As usual the code used in this tutorial is
available on GitHub. You can find the link in the end of this post.
Easiest way is to install it with pip:
That’s it. It’s ready to be used. Make sure you update your requirements.txt.
The default language of the app is English. It already come with some localization and language support. Currently the
supported languages are: de, es_AR, fr, pl, ru, zh_CN. Unless you want to use any of those languages in your project,
you don’t need to add django_filter to the INSTALLED_APPS.
Create a file named filters.py inside your app folder:
The view is as simple as:
Then a route:
And finally the template:
The magic happens inside the UserFilter class. We simply have to pass the request.GET data to the UserFilter
class, along with the QuerySet we want to filter. It will generate a Django Form with the search fields as well as
return the filtered QuerySet.
So basically we will be working inside the UserFilter definition and the HTML template, displaying properly the data.
This is what the initial example looks like:
And after submitting the form:
Using The Generic Class-Based View
If you won’t be doing anything special inside the view function, you can easily replace it with the
django-filter’s generic class-based view.
You may either pass a model or a filterset_class as a parameter. We will be working with the
filterset_class, so to give us more flexibility:
Note that I also passed the template_name as a parameter. By default django-filter will look for the template
based on the model’s app and its name, following the logic: <app_name>/<model_name>_filter.html.
Since I’m implementing a filter for the Django User, which lives inside the auth app (and I don’t have access to it),
the django-filter library would look for a template in the path: auth/user_filter.html.
Actually this is an extra for the post. In the end, the filter.form we access in the template is just a regular
Django form. But in case you are wondering how to make it look prettier, here is what we can do: