Problema
Como se recomienda en la publicación de blog Mejores prácticas para diseñar una API RESTful pragmática , me gustaría agregar un fields
parámetro de consulta a una API basada en Django Rest Framework que permite al usuario seleccionar solo un subconjunto de campos por recurso.
Ejemplo
Serializador:
class IdentitySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Identity
fields = ('id', 'url', 'type', 'data')
Una consulta regular devolvería todos los campos.
GET /identities/
[
{
"id": 1,
"url": "http://localhost:8000/api/identities/1/",
"type": 5,
"data": "John Doe"
},
...
]
Una consulta con el fields
parámetro solo debe devolver un subconjunto de los campos:
GET /identities/?fields=id,data
[
{
"id": 1,
"data": "John Doe"
},
...
]
Una consulta con campos no válidos debe ignorar los campos no válidos o generar un error de cliente.
Objetivo
¿Es esto posible fuera de la caja de alguna manera? Si no es así, ¿cuál es la forma más sencilla de implementar esto? ¿Existe un paquete de terceros que ya haga esto?
fuente
QUERY_PARAMS
aquery_params
en versiones recientes de Django, pero aparte de eso, esto funciona a las mil maravillas.requests
existe como miembro decontext
. Si bien lo hace en producción, no lo hace cuando se ejecutan pruebas unitarias que crean los objetos manualmente.Esta funcionalidad está disponible en un paquete de terceros .
Declare su serializador así:
Entonces, los campos ahora se pueden especificar (del lado del cliente) mediante el uso de argumentos de consulta:
El filtrado de exclusión también es posible, por ejemplo, para devolver todos los campos excepto id:
descargo de responsabilidad: soy el autor / mantenedor.
fuente
dbrgn
implementación tiene algunas diferencias: 1. no admite excluir confields!=key1,key2
. 2. también modifica los serializadores fuera del contexto de la solicitud GET, lo que puede romper y romperá algunas solicitudes PUT / POST. 3. no acumula campos confields=key1&fields=key2
, por ejemplo , lo que es bueno para las aplicaciones ajax. También tiene cobertura de prueba cero, lo cual es algo inusual en OSS.serializers.py
views.py
fuente
Configurar una nueva clase de serializador de paginación
Hacer serializador dinámico
Por último, use una combinación de homemage para sus APIViews
Solicitud
Ahora, cuando solicita un recurso, puede agregar un parámetro
fields
para mostrar solo los campos especificados en la URL./?fields=field1,field2
Puede encontrar un recordatorio aquí: https://gist.github.com/Kmaschta/e28cf21fb3f0b90c597a
fuente
Puede probar Dynamic REST , que tiene soporte para campos dinámicos (inclusión, exclusión), objetos incrustados / descargados, filtrado, ordenamiento, paginación y más.
fuente
Esta funcionalidad la hemos proporcionado en drf_tweaks / control-over-serialized-fields .
Si usa nuestros serializadores, todo lo que necesita es pasar el
?fields=x,y,z
parámetro en la consulta.fuente
Para datos anidados, estoy usando Django Rest Framework con el paquete recomendado en los documentos , drf-flexfields
Esto le permite restringir los campos devueltos tanto en el objeto principal como en el secundario. Las instrucciones en el archivo Léame son buenas, solo algunas cosas a tener en cuenta:
La URL parece necesitar el / como este '/ person /? Expand = country & fields = id, name, country' en lugar de como está escrito en el archivo Léame '/ person? Expand = country & fields = id, name, country'
El nombre del objeto anidado y su nombre relacionado deben ser completamente coherentes, lo que no es necesario de otro modo.
Si tiene 'muchos', por ejemplo, un país puede tener muchos estados, deberá establecer 'muchos': Verdadero en el serializador como se describe en los documentos.
fuente
Si desea algo flexible como GraphQL, puede usar django-restql . Admite datos anidados (tanto planos como iterables).
Ejemplo
Una solicitud regular devuelve todos los campos.
GET /users
Por
query
otro lado, una solicitud con el parámetro devuelve solo un subconjunto de los campos:GET /users/?query={id, username}
Con django-restql puede acceder a campos anidados de cualquier nivel. P.ej
GET /users/?query={id, username, date_joined{year}}
Para campos anidados iterables, por ejemplo, grupos de usuarios.
GET /users/?query={id, username, groups{id, name}}
fuente