Pular para conteúdo

Aplicando filtros com django_filters

Caso você queira utilizar filtros em uma listagem de um model, você pode utilizar o django_filters.

Como funciona?

O django_filters é um modulo que permite a criação de filtros para os models, com ele é possível criar filtros para os campos do model, e aplicar esses filtros na listagem do model ou em qualquer outra view que desejar.

Configurando o Filter

Crie um arquivo filters.py na app requerida para configuração do modulo django_filters.

from django import forms
from django_filters import filterset

from .models import Livro


class LivroFilter(filterset.FilterSet):

    titulo = filterset.CharFilter(
        label="Titulo",
        lookup_expr="icontains",
        widget=forms.TextInput(attrs={"class": "form-control"}),
    )

    autor = filterset.CharFilter(
        label="Autor",
        method="filter_autor",
        widget=forms.TextInput(attrs={"class": "form-control"}),
    )

    created_on = filterset.DateFilter(
        label="Criado depois de",
        lookup_expr="gte",
        widget=forms.DateInput(attrs={"type": "date", "class": "form-control"}),
    )

    def filter_autor(self, queryset, name, value):
        return queryset.filter(autor__nome__icontains=value)

    class Meta:
        model = Livro
        fields = ["titulo", "autor", "created_on"]

Lembre-se sempre de utilizar o lookup_expr corretamente para definir o tipo de filtro que será aplicado, como no exemplo o icontains que é um filtro de texto que busca por parte do texto e o gte que busca por datas maiores ou iguais.

Se necessário uma filtragem mais complexa, é possível criar filtros customizados, como no exemplo o filter_autor.

Você é capaz de passar atributos comuns de um form, como label, widget, required, etc.

Configurando a View

Sua view deverá herdar de django_filters.views.FilterView e definir o atributo filterset_class com o filtro que você criou.

from django_filters.views import FilterView

from teste_livro.filter import LivroFilter
from teste_livro.models import Livro


class LivroListView(FilterView, BaseListView):
    ...
    model = Livro
    filterset_class = LivroFilter

Configurando o Template

Os templates list do Core já possuem uma verificação para renderizar o filtro corretamente.

Mas se for necessário utilizar o filtro em outro template, é necessário renderizar o filtro manualmente. Use filter.form ou filter.form.as_p no template.

Segue um exemplo de como utilizar o filtro no template:

<form method="get">
    <div class="d-flex flex-column flex-md-row justify-content-start mb-4 gap-large">
        {% for filtro in filter.form %}
            <div class="form-floating">
                {{ filtro }}
                {{ filtro.label_tag }}
            </div>
        {% endfor %}
        <div class="align-self-center">
            <button class="br-button secondary block" type="submit">
                <i class="fas fa-filter mr-2"></i> Filtrar
            </button>
        </div>
    </div>
</form>

Leia mais

Acesse a documentação oficial para mais informações sobre o django_filters.