Apr 24, 2017

How To Use Django Filter

Luisa María Reyes Suárez


Nowadays, all web applications have a searcher in its pages, so the user can search the displayed items by its title, date, etc. This functionality in Django is very simple thanks to Django-filter app. Then, let’s we talk about this app and how it’s used.

What is Django-filter?

Django-filter is a generic and reusable application, so it avoids the code repetition (DRY: Don't Repeat Yourself) and this app allow to user to filter the querysets dynamically form.


Install Django-filter using pip

pip install django-filter

Then, add ‘django-filters’ in your settings.py:


And you mustn't forget update your requirements.txt.

All installed? Ok, we start below.


First of all we’ll create a model in the models.py of our app folder and add the data that we want to do the queryset, for example:

class Film(models.Model):
	title = models.CharField(max_lenght=255)
	description = models.CharField()
	duration = models.IntegerField()
	price = models.DecimalField()

Then, we’ll create a new file named filters.py inside our app folder:

import django_filters

from films.models import Film

class FilmFilter(django_filters.FilterSet):
	class Meta:
		model = Film

Just need to create a simple view and a route and it’s ready! The user can search the films by its title, duration and price, is it easy or isn’t it?

Well, we have implemented a basic filter, for default the filter filters the exact field, if we want that the filter would be more flexible (case-insensitive and it could search part of the title, etc.) we must modify a little the filter with filter arguments (more information about the arguments here):

class FilmFilter(django_filters.FilterSet):
	title = django_filters.CharFilter(lookup_expr='icontains')
	duration = django_filters.NumberFilter()
	price_gt = django_filters.NumberFilter(name='price', lookup_expr='gt')
	price_lt = django_filters.NumberFilter(name='price', lookup_expr='lt')
	class Meta:
		model = Film

As you can see, if we declare the fields as variables, we do not need to define them in the Meta class, but we could modify the filters in the Meta class too:

class FilmFilter(django_filters.FilterSet):
    class Meta:
        model = Film
        fields = {'title': ['icontains'],
		          'duration': ['exact'],
                  'price': ['gt', 'lt'],

The two previous examples generate 4 search fields: ‘title_icontains', ‘duration', 'price_gt' and 'price_lt', you can use either of the two examples.

Finally, we can use a function-based view or  a class-based view:

Function-based view

# views.py
def film_list(request):
	films= Film.object.all()
	filter = FilmFilter(request.GET, queryset = films)
	return render(request, 'myapp/my_template.html', {'filter' : filter})

# urls.py
urlpatterns = [
    url(r'^search/$’, views.film_list, name='searcher'),

Class-based view

# urls.py
urlpatterns = [
    url(r'^search/$', FilterView.as_view(filterset_class=FilmFilter,
    	template_name='myapp/my_template.html'), name='searcher'),

Note: If you don't specify the template name as parameter, django-filter will search the template for default and it’s <app_name>/<model_name>_filter.html.

Leave a comment