Tengo una consulta bastante simple que me gustaría hacer a través del ORM, pero no puedo resolverlo.
Tengo tres modelos:
Ubicación (un lugar), Atributo (un atributo que podría tener un lugar) y Calificación (un modelo M2M 'a través' que también contiene un campo de puntuación)
Quiero elegir algunos atributos importantes y poder clasificar mis ubicaciones según esos atributos, es decir, una puntuación total más alta sobre todos los atributos seleccionados = mejor.
Puedo usar el siguiente SQL para obtener lo que quiero:
select location_id, sum(score)
from locations_rating
where attribute_id in (1,2,3)
group by location_id order by sum desc;
que regresa
location_id | sum
-------------+-----
21 | 12
3 | 11
Lo más cerca que puedo estar con el ORM es:
Rating.objects.filter(
attribute__in=attributes).annotate(
acount=Count('location')).aggregate(Sum('score'))
Que vuelve
{'score__sum': 23}
es decir, la suma de todos, no agrupados por ubicación.
¿Alguna forma de evitar esto? Podría ejecutar el SQL manualmente, pero prefiero ir a través del ORM para mantener la coherencia.
Gracias
fuente
Respuestas:
Prueba esto:
Rating.objects.filter(attribute__in=attributes) \ .values('location') \ .annotate(score = Sum('score')) \ .order_by('-score')
fuente
aggregate
es para el conjunto de resultados completo,annotate
para filas individuales (agrupadas).'dict' object has no attribute '_meta'
con ese QuerySet?[{"location": 53, "score": 100}, {"location": 54, "score": 104}]
¿Puedes probar esto?
Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).
fuente