Mam dość proste zapytanie, które chciałbym wykonać za pośrednictwem ORM, ale nie mogę tego rozgryźć.
Mam trzy modele:
Lokalizacja (miejsce), atrybut (atrybut, który może mieć miejsce) i ocena (model M2M „do”, który zawiera również pole punktacji)
Chcę wybrać kilka ważnych atrybutów i móc uszeregować moje lokalizacje według tych atrybutów - tj. Wyższy wynik całkowity dla wszystkich wybranych atrybutów = lepszy.
Mogę użyć następującego SQL, aby uzyskać to, czego chcę:
select location_id, sum(score)
from locations_rating
where attribute_id in (1,2,3)
group by location_id order by sum desc;
który powraca
location_id | sum
-------------+-----
21 | 12
3 | 11
Najbliższe, co mogę uzyskać dzięki ORM, to:
Rating.objects.filter(
attribute__in=attributes).annotate(
acount=Count('location')).aggregate(Sum('score'))
Który powraca
{'score__sum': 23}
tj. suma wszystkich, nie pogrupowanych według lokalizacji.
Jakoś to obejść? Mógłbym wykonać SQL ręcznie, ale wolałbym przejść przez ORM, aby zachować spójność.
Dzięki
django
django-aggregation
Guy Bowden
źródło
źródło
Odpowiedzi:
Spróbuj tego:
Rating.objects.filter(attribute__in=attributes) \ .values('location') \ .annotate(score = Sum('score')) \ .order_by('-score')
źródło
aggregate
dotyczy pełnego zestawu wynikówannotate
dla pojedynczych (zgrupowanych) wierszy.'dict' object has no attribute '_meta'
taki zestaw QuerySet?[{"location": 53, "score": 100}, {"location": 54, "score": 104}]
Możesz tego spróbować.
Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).
źródło