[pyar] Ayuda para api con django-rest-framework

Germán L. Osella Massa gosella en gmail.com
Jue Ene 4 08:58:00 ART 2018


El día 3 de enero de 2018, 18:28, Federico Gonzalez
<federicogonzalez761 en gmail.com> escribió:
> Buenas,
>
> Tengo un problema con la api que estoy armando y quería consultar para ver
> si alguien tenia una solución.
> Tengo un modelo que quiero hacer una api rest en la cual poder filtrar,
> ordenar, paginar y buscar.
> Actualmente hace todo eso pero me encontré con un problema al querer ordenar
> y/o filtrar por datos del modelo que no son fields sino que property's (no
> estan en la db).
> Para el caso de ordenar logre que algo me funcione (aunque no me gusta
> mucho) pero para el caso de filtrar todavía no logre hacerlo.
> Para que vean el código:
> 1- El Serializer del modelo: serializer
> 2- El modelo: model
>
> En ese código pueden ver que por ejemplo attendees_count es una property que
> se calcula en el serializer/viewset y la api no solo lo muestra sino que
> puede ordenar por ese "campo" pero no puede filtrar por ese campo.
> En resumen, lo que me gustaria es primero saber que opinan de eso, segundo
> ver como puedo hacer lo mismo con esta property: last_date y por ultimo
> saber si se puede filtrar por alguna property calculada.
>
> Saludos
> Fede

Hola Fede! ¿Cómo estás?

Antes que anda, aclaro que no soy un experto en Django y mi info puede
estar desactualizada ;-)

Por lo que tengo entendido, el ORM de Django traduce los filter() en
una cláusula WHERE de un query SQL, por lo que no podrías usar
properties como parte de la condición del filter (ya que en la DB no
existiría como un campo). :-(

Lo único que se me ocurre sería usar annotate() para aumentar el
QuerySet del Model, transformando así las properties en campos
(calculados) de la DB para así poder filter/ordenar como lo harías con
un campo "normal".

En [1] tenés un ejemplo de como definir en un Model un QuerySet
aumentado con annotate().

La contra es que no sería muy DRY, dado que tendías la misma lógica en
los campos calculados y en las properties.
Probablemente la opción a evaluar sería sacar las properties y
manejarte directamente con los campos calculados.

Por lo que vi (muy por arriba), los queries que tenés en las
properties deberían poder mapearse a los correspondientes campos
calculados usando annotate.
Mirá al final de [2] como para tener un ejemplo de lo que se podría hacer.

Otra consideración sería ver que tan frecuentemente necesitás los
valores de los campos calculados, dado que serían computados por cada
query a ese Model (y podría ser costoso).
Si los valores de esos campos sólo se necesitan esporádicamente, por
ahí sería más negocio tener un segundo Manager con las anotaciones y
usarlo desde django-rest-framework sólo cuando se necesitan los campos
extra, dejando el Manager por defecto para las consultas más
frecuentes que no los necesitan.

Saludos,
Germán

[1] https://stackoverflow.com/a/42491803
[2] https://brobin.me/blog/2017/06/django-queryset-annotations-for-increased-performance/


Más información sobre la lista de distribución pyar