Parámetros de consulta#

Este es el undécimo artículo de la serie tutorial de Django Ninja.
En el artículo anterior analizamos la forma de manejar los parámetros de ruta en la URL de solicitud.
Este artículo presentará los parámetros de consulta (query parameters), una parte importante en las API RESTful utilizada para transmitir información adicional como condiciones de filtrado.
Manejar los parámetros de consulta en Django Ninja es muy sencillo e intuitivo, y podemos lograrlo de múltiples maneras.
Todos los cambios de código de este artículo se pueden consultar en este PR.
Proyecto de ejemplo en GitHub#
1. ¿Qué son los parámetros de consulta?#
Los parámetros de consulta son parámetros opcionales en la URL. Suelen ubicarse después del path con el formato ?key=value y se utilizan para transmitir información adicional.
Por ejemplo, cuando necesitamos filtrar las publicaciones de un autor específico, el path de la URL podría escribirse así:
La URL transmitió el parámetro de consulta author=john, lo que indica que deseamos filtrar las publicaciones escritas por John.
2. Cambios en el proyecto de ejemplo#
Para presentar los parámetros de consulta de forma más realista, necesitamos modificar la API previa de «obtener todas las publicaciones» y añadir una funcionalidad simple de «filtrado».
Por cierto, la funcionalidad de filtrado complejo se presentará en la «Entrega 23: Filtrado (Filtering)».
Tras la modificación, cuando la solicitud incluya parámetros de consulta, la API podrá usar esos parámetros para limitar los resultados de la consulta. Como se muestra a continuación:
@router.get(path='/posts/')
def get_posts(request: HttpRequest, title: None | str = None):
posts = Post.objects.all()
if title:
posts = posts.filter(title__icontains=title) # Implementar lógica de filtrado
return posts
Aquí realizamos el filtrado según el «título de la publicación».
Pequeño recordatorio: La API del proyecto todavía no se puede utilizar: primero porque la base de datos no contiene datos, y segundo porque todavía no hemos escrito el Schema correspondiente. En esta etapa solo sirve como referencia de lectura. Pero no te preocupes, ¡muy pronto la haremos funcionar! ☺️
Bien, tras modificar el código, procedamos con la explicación.
3. Uso de Query Parameters en Django Ninja#
En Django Ninja, la forma más sencilla de manejar los parámetros de consulta es incluirlos directamente como parámetros opcionales de la función view: a través del valor predeterminado None:
En este ejemplo, el parámetro title se define como una cadena opcional (None | str = None).
- Si la URL contiene el parámetro de consulta
title, Django Ninja tomará automáticamente su valor como argumento y lo pasará a la funciónget_posts. - Si la URL no contiene este parámetro de consulta, la función no recibirá el argumento, y el valor de
titledentro de la función seráNone, ya que cuenta con un valor predeterminado.
Con respecto a este ejemplo, también debemos prestar atención a los siguientes puntos:
- Los parámetros de consulta no necesitan escribirse en la ruta del parámetro
pathdel decoradorrouter. - Los parámetros de consulta suelen tener un valor predeterminado, ya sea un valor específico o el
Nonemencionado anteriormente. Si falta el valor predeterminado, cuando el parámetro de consulta no exista, Django Ninja devolverá una respuesta 422. - Cuando el valor predeterminado sea
None, debes prestar atención a la sintaxis de type hints:None | str = None(equivalente aOptional[str] = None). - Al igual que los parámetros de ruta, los parámetros de consulta realizan la conversión de tipos según los type hints de la función. Si no se marca el tipo, el tipo predeterminado de ambos será
str, ya que las URL son esencialmente cadenas de texto.
La sintaxis anterior es simple y directa, adecuada para la mayoría de los casos.
Sin embargo, cuando necesitamos realizar validaciones o restricciones más complejas sobre los parámetros de consulta, debemos utilizar una técnica avanzada: Query.
4. Uso del objeto Query#
Cuando necesitamos un control más detallado, como limitar la longitud o el rango de los parámetros de consulta, o añadir información adicional a la documentación de la API, podemos usar Query para configurar y manejar los parámetros de consulta.
Debo admitir que antes casi no utilizaba Query en mis desarrollos, pero conocer el 20% de sus características más importantes sin duda resultará de gran ayuda.
Introducción a Query#
A través del objeto Query, podemos realizar definiciones y validaciones más precisas para los parámetros de consulta.
De hecho, si has visto el código fuente de Django Ninja, descubrirás que en realidad es una función; solo que devuelve un objeto de clase con el mismo nombre.
Para facilitar la explicación, lo llamaremos colectivamente objeto Query. Después de todo, en Python todo es un objeto.
Revisa este ejemplo modificado:
from ninja import Query, Router
...
@router.get(path='/posts/')
def get_posts(request: HttpRequest, title: None | str = Query(None)):
...
Es casi equivalente a la sintaxis original: (Aún existen diferencias sutiles, pero se pueden ignorar por ahora)
Podrías preguntarte por qué cambiarías a una forma de escribir más compleja sin obtener beneficios adicionales.
Esto se debe, por supuesto, a que la sintaxis más compleja permite hacer muchas más cosas.
Limitar la longitud de la cadena de consulta#
Por ejemplo, si quisiéramos limitar la cadena de consulta title para que no sea ni demasiado larga ni demasiado corta.
Supongamos que requerimos una longitud de entre 2 y 10 caracteres.
En este caso, podrías escribirlo así:
def get_posts(
request: HttpRequest,
title: None | str = Query(None, min_length=2, max_length=10),
):
En este ejemplo, utilizamos Query para definir el parámetro de consulta title y le proporcionamos adicionalmente las configuraciones min_length y max_length al inicializar Query.
Esto garantiza que la longitud del parámetro de consulta title esté entre 2 y 10 caracteres.
Si el title ingresado por el usuario no cumple con esta restricción de longitud, como se mencionó en el artículo anterior, Django Ninja devolverá automáticamente una respuesta con código de estado 422, sin necesidad de que manejemos manualmente la lógica de validación ni las respuestas correspondientes.
// 422 Unprocessable Entity
{
"detail": [
{
"type": "string_too_short", // Parámetro de consulta demasiado corto
"loc": [
"title",
"title"
],
"msg": "String should have at least 2 characters",
"ctx": {
"min_length": 2
}
}
]
}
Otros parámetros comunes de Query#
Además de min_length y max_length, Query ofrece muchos otros parámetros útiles para restringir las condiciones de consulta o añadir información suplementaria a la documentación de la API. Entre los más comunes están:
gt,ge: El valor del parámetro de consulta debe ser mayor que o mayor o igual que cierto número.lt,le: El valor del parámetro de consulta debe ser menor que o menor o igual que cierto número.example,examples: Proporciona valores de ejemplo para los parámetros de consulta en la documentación de la API, facilitando a los usuarios comprender el uso del parámetro.
No demostraremos esta parte por ahora.
Resumen y siguientes pasos#
Los parámetros de consulta son un componente común e importante en las API RESTful. En Django Ninja, podemos manejar los parámetros de consulta de forma sencilla o utilizar Query para lograr validaciones y controles más avanzados.
Habiendo comprendido cómo maneja Django Ninja los parámetros relacionados con la URL, lo que viene a continuación es el plato fuerte.
A continuación, exploraremos cómo manejar el request body de HTTP en Django Ninja y cómo usar Schema para la validación y deserialización de datos, permitiéndonos manejar información de solicitudes complejas con flexibilidad.