Cuando se usa CoreAPI con DRF y DjangoFilterBackend
habilitado, el cliente también intenta asignar todos los campos para acciones de creación, actualización o actualización parcial a los parámetros de consulta. Esto rompe la capacidad del cliente para utilizar estos métodos.
Si tenemos una solicitud que intenta crear un libro con un nombre, y el nombre también es un campo filtrable en nuestro modelo:
# book views
class BookViewSet():
filter_fields = ('name',)
# ...
// schema
client.action('book', 'create', { 'name': 'My Awesome Book' });
Esto creará una solicitud con el nombre en el parámetro de URL y el cuerpo de la solicitud. Este no es el comportamiento esperado.
POST /api/book?name=My%20Awesome%20Book
name=My Awesome Book
Hemos solucionado esto en nuestro código al señalar nuestro backend de filtro DRF a una anulación personalizada con el siguiente código:
class OnlyFilterOnReadDjangoFilterBackend(DjangoFilterBackend):
""" A filter backend that only allows for filtering by properties on
actions deemed as safe. This means that create, update, and partial_update
actions will not provide filter options.
"""
SAFE_ACTIONS = ('list', 'retrieve')
def get_schema_fields(self, view):
if view.action in self.SAFE_ACTIONS:
return super().get_schema_fields(view)
return []
Hola @Sonictherocketman. Gracias por el informe.
Lo primero que pensé es que se trata de un error con la API del cliente: no distingue adecuadamente entre los parámetros de la cadena de consulta y el cuerpo de la solicitud al construir la solicitud.
En general, simplemente deshabilitar el filtrado de acciones no seguras no es correcto. El filtrado se produce cuando se establece el conjunto de consultas base contra el que se realizará una actualización.
Dejaré esto abierto por ahora, solo para pensarlo.
También creo que es un problema del cliente, pero cuanto más lo pienso, siento que las acciones realmente no tienen ningún sentido en las consultas de escritura (especialmente escribir en un recurso específico) y, en mi opinión, el esquema no debería tener esos campos si no se deben usar.
Gracias por la respuesta rápida y estoy muy interesado en lo que piensas sobre esto.
Más o menos, creo que estamos limitados aquí por nuestros deseos de generar código _automágico_ superando a la tecnología (en su estado actual).
Hay muchas cosas que no podemos (todavía) hacer con esquemas (en cualquiera de los formatos disponibles) que nos gustaría; por ejemplo, con CoreAPI, aún no podemos agrupar parámetros para que se muestre un filtro de rango de fechas. que están relacionados. (Hay mucho más que podemos hacer escribiendo esquemas a mano, pero nadie quiere hacer eso, por supuesto).
Pero evoluciona, ya medida que lo hace, también lo hacen las herramientas. Mejorará.
Que esta línea en particular:
client.action('book', 'create', { 'name': 'My Awesome Book' });
usa el mismo dict para la cadena de consulta y el cuerpo de la solicitud no es excelente. Supongo que es la fuga de abstracción. Realmente desea construir esta solicitud _a mano_, especificando los parámetros de consulta y el cuerpo en lugares separados.
Actualmente, esto no es algo que podamos abordar aquí. Aunque gracias de nuevo por el informe.
Comentario más útil
Hola @Sonictherocketman. Gracias por el informe.
Lo primero que pensé es que se trata de un error con la API del cliente: no distingue adecuadamente entre los parámetros de la cadena de consulta y el cuerpo de la solicitud al construir la solicitud.
En general, simplemente deshabilitar el filtrado de acciones no seguras no es correcto. El filtrado se produce cuando se establece el conjunto de consultas base contra el que se realizará una actualización.
Dejaré esto abierto por ahora, solo para pensarlo.