Skip to content

Instantly share code, notes, and snippets.

@mrroot5
Last active May 14, 2020 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrroot5/f93faaece72e04517ec841be71e079c1 to your computer and use it in GitHub Desktop.
Save mrroot5/f93faaece72e04517ec841be71e079c1 to your computer and use it in GitHub Desktop.
Django Rest Framework filters. Keywords: drf, django rest framework, filters, drf filters, django rest framework filters.

Introducción

En este snippet pretendemos hacer varios filtros diferentes para una aplicación django que usa django rest framework (DRF).

No se cubre la instalación, configuración y puesta en marcha de django filters. Aquí tienes varios enlaces con información relevante:

Filtrado DRF Integración DRF django filter github

IMPORTANTE: Los filtros necesitan de un serializer + viewset que creamos con DRF.

Filtrado común

Este es el ejemplo más común. Con agregar unos pocos parámetros tenemos hecho el filtrado. Documentación oficial.

class ProductList(generics.ListAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = Access.objects.all()
    serializer_class = AccessSerializer
    filter_fields = ('category', 'in_stock')

En el ejemplo, agregamos un permiso para exigir login al usar la API. Además:

  • Con el query_set obtenemos los datos que se van a mostrar, en el ejemplo, todos.

  • Por su lado, serializer_class hace referencia al serializer encargado de determinar que campos se podrán consultar.

  • Por último, lo que nos interesa en este ejemplo, el filter_fields que se emplea para realizar el filtrado de campos, por ejemplo, con un string indicando la categoria por la que filtrar los resultados.

Filtrado date o datetime

¿Qué pasa si queremos filtrar por fechas? Es bastante improbable que queramos una fecha y horas específicias, menos aún el el formato que nos muestra django, algo como esto: 2018-04-02T16:09:09.949331Z. Lo lógico sería filtrar si contiene la fecha o está en un rango mayor o menor a una fecha dada.

Contiene la fecha

Ideal para devolver los resultados de, por ejemplo, un día concreto. En el ejemplo usaremos un campo datetime en el modelo pero filtraremos por un date para obtener el día.

class ProductListDayDateFilter(filters.FilterSet):
    # Hacemos filtrado por fecha
    last_update_contains = django_filters.DateFilter(name="last_update", lookup_expr='contains')
    class Meta:
        model = ProductList
        # Especificamos el nombre del campo filtro
        fields = ['last_update_contains']


class ProductListViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = ProductList.objects.all()
    serializer_class = ProductListSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    # Especificamos el filtro que se va a emplear
    filter_class = ProductListDayDateFilter

Rango mayor o menor

Ideal para devolver los resultados de, por ejemplo, una semana. Dependiendo de como lo usemos también vale para consultar el día pero es mucho menos intuitivo que la opción de Contiene la fecha.

class ProductListDateLteGteFilter(filters.FilterSet):
    # Filtra por las fechas inferiores a la introducida
    last_update_lte = django_filters.DateTimeFilter(name="last_update", lookup_expr='lte')
    # Filtra por las fechas mayores a la introducida
    last_update_gte = django_filters.DateTimeFilter(name="last_update", lookup_expr='gte')
    class Meta:
        model = ProductListnswer
        # Especificamos el nombre de los campos filtro
        fields = ['last_update_gte', 'last_update_lte']


class ProductListViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = ProductList.objects.all()
    serializer_class = ProductListSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    # Especificamos el filtro que se va a emplear
    filter_class = ProductListDateLteGteFilter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment