¿Es posible filtrar dentro de una anotación?Anotación de Django con filtro anidado
En mi mente algo como esto (que en realidad no funciona)
Student.objects.all().annotate(Count('attendance').filter(type="Excused"))
La tabla resultante tendría a cada estudiante con el número de ausencias justificadas. Mirar a través de los filtros de documentación solo puede ser antes o después de la anotación, lo que no daría los resultados deseados.
Una solución es esta
for student in Student.objects.all():
student.num_excused_absence = Attendance.objects.filter(student=student, type="Excused").count()
Esto funciona, pero hace muchas preguntas, en una aplicación real esto puede ser excesivamente largo. Creo que este tipo de declaración es posible en SQL pero preferiría permanecer con ORM si es posible. Incluso intenté hacer dos consultas separadas (una para todos los estudiantes, otra para obtener el total) y las combiné con |. La combinación del total cambió :(
Algunas reflexiones después de la lectura de las respuestas y los comentarios
He resuelto el problema de asistencia utilizando SQL adicional here.
- Timmy's blog post era útil. Mi respuesta se basa fuera de ella.
- La respuesta de hash1baby funciona pero parece tan compleja como sql. También requiere ejecutar sql y luego agregar el resultado en un bucle for. Esto es malo para mí porque estoy combinando muchas de estas consultas de filtrado. Mi solución construye un gran queryset w con muchos filtros y más y lo ejecuta todo a la vez.
- Si el rendimiento no es un problema, sugiero que el bucle for funcione. Es de lejos el más fácil de entender.
He escrito una publicación en el blog sobre esto, ya que no es posible (afaik) sin utilizar SQL sin formato o simplemente iterar sobre los resultados: http://timmyomahony.com/blog/filtering-annotations-django/ –
Hay una nueva solución para esto en el ORM a partir de Django 1.8. Ver mi respuesta a continuación. – gordonc