Personalización de filtros en Django REST Framework

Requisito previo: agregar filtrado en las API: Django REST Framework [artículo necesario en lin publicado todavía]

Los filtros de Django facilitan el filtrado del conjunto de consultas para recuperar los resultados relevantes en función de los valores asignados a los campos de filtro. Pero, ¿qué pasa si el usuario quiere recuperar detalles dentro de un rango determinado? Digamos, por ejemplo, que el usuario necesita obtener detalles de los robots según el rango de precios. Aquí viene la necesidad de personalizar los filtros. Vamos a crear y aplicar un filtro personalizado al modelo de robot para que el usuario pueda recuperar los detalles del robot al proporcionar el nombre de la categoría del robot, el nombre del fabricante, la moneda, el rango de fechas de fabricación y/o el rango de precios.  

Crearemos una nueva clase llamada clase RobotFilter , que es una subclase de la clase django_filters.FilterSet . Declaremos las importaciones

Python3

from django_filters import FilterSet, AllValuesFilter
from django_filters import DateTimeFilter, NumberFilter

Ahora, puede agregar el siguiente código antes de la clase RobotList.

Python3

class RobotFilter(FilterSet):
    from_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
                                             lookup_expr='gte')
    to_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
                                           lookup_expr='lte')
    min_price = NumberFilter(field_name='price', lookup_expr='gte')
    max_price = NumberFilter(field_name='price', lookup_expr='lte')
    robotcategory_name = AllValuesFilter(field_name='robot_category__name')
    manufacturer_name = AllValuesFilter(field_name='manufacturer__name')
  
    class Meta:
        model = Robot
        fields = (
            'name',
            'currency',
            'from_manufacturing_date',
            'to_manufacturing_date',
            'min_price',
            'max_price',
            'robotcategory_name',
            'manufacturer_name',
            )

Veamos los atributos declarados en la clase RobotFilter.

  • from_manufacturing_date
  • hasta_fecha_de_fabricación
  • precio_min
  • precio_máximo
  • robotcategory_name
  • Nombre del Fabricante

from_manufacturing_date: es un atributo de instancia de django_filters.DateTimeFilter que filtra los robots cuyo valor de manufacturing_date es mayor o igual que el valor DateTime especificado. Aquí, en DateTimeFilter, hay dos parámetros llamados field_name y lookup_expr . field_name tiene la fecha_de_fabricación (para filtrar) y se aplica ‘gte’ (mayor o igual que) a lookup_expr.

to_manufacturing_date: Es un atributo de instancia de django_filters.DateTimeFilter que filtra los robots cuyo valor de manufacturing_date es menor o igual que el valor DateTime especificado. Aquí, en DateTimeFilter, hay dos parámetros llamados field_name y lookup_expr . En el campo_nombre, mencionamos la fecha_de_fabricación, y se aplica ‘lte’ (menor o igual que) a la expresión_buscada.

min_price: Es un atributo de instancia de django_filters.NumberFilter que filtra los robots cuyo valor de precio es mayor o igual al valor de precio especificado.

max_price: Es un atributo de instancia de django_filters.NumberFilter que filtra los robots cuyo valor de precio es menor o igual al valor de precio especificado.

robotcategory_name: es un atributo de instancia django_filters.AllValuesFilter que filtra los robots cuyo nombre de categoría de robot coincide con el valor de string especificado. Puede notar que hay un guión bajo doble (__) en el valor proporcionado a field_name , entre robot_category y name. field_name usa el guión bajo doble de Django para leerlo como el campo de nombre para el modelo RobotCategory. Esto ayuda a recuperar los detalles del robot en función del nombre de la categoría del robot en lugar de su ID de pk.

manufacturer_name: es un atributo de instancia de django_filters.AllValuesFilter que filtra los robots cuyo nombre de fabricante coincide con el valor de string especificado. field_name usa el guión bajo doble de Django para leer el valor ‘manufacturer__name’ como el campo de nombre para el modelo Manufacturer. Esto ayuda a recuperar los detalles del robot según el nombre del fabricante en lugar de su ID de paquete.

La clase RobotFilter también define una clase interna Meta . Esta clase tiene dos atributos modelo y campos . El atributo del modelo especifica el modelo (Robot) para filtrar. Y, el atributo de campos contiene nombres de campo y nombres de filtro (como una tupla de strings) para incluir en los filtros para el modelo mencionado (Robot). 

Usemos la clase RobotFilter en nuestra clase RobotList . El código de la siguiente manera

Python3

class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
    # customized filter class
    filter_class = RobotFilter
    search_fields = (
        '^name',
    )
    ordering_fields = (
        'price',
    )

Filtremos los robots dentro de una fecha de fabricación. El comando HTTPie es

http “:8000/robot/?from_manufacturing_date=2019-10-01&to_manufacturing_date=2020-03-01”

Producción:

Filtremos los robots según el nombre de la categoría del robot y el nombre del fabricante. El comando HTTPie de la siguiente manera

http “:8000/robot/?robotcategory_name=Robots articulados&manufacturer_name=Fanuc”

Producción:

Filtremos los robots según el rango de precios. El comando HTTPie es

http “:8000/robot/?min_price=10000&max_price=20000¤cy=USD”

Producción:

Filtremos los robots usando la función de API navegable. Puede navegar por la siguiente URL y hacer clic en el botón de filtro.

http://127.0.0.1:8000/robot/

Puede completar los valores para filtrar contra robots. Compartiendo la captura de pantalla a continuación

Al hacer clic en el botón Enviar, obtendrá resultados filtrados. Compartiendo la captura de pantalla a continuación

Publicación traducida automáticamente

Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *