Як згрупувати за І об'єднати за допомогою Django


83

У мене є досить простий запит, який я хотів би зробити через ORM, але не можу зрозуміти це ..

У мене є три моделі:

Місце (місце), атрибут (атрибут, який може мати місце) та рейтинг (модель M2M "через", яка також містить поле оцінки)

Я хочу вибрати деякі важливі атрибути та мати можливість ранжувати моє місце розташування за цими атрибутами - тобто вищий загальний бал за всіма вибраними атрибутами = краще.

Я можу використовувати наступний SQL, щоб отримати те, що я хочу:

select location_id, sum(score) 
    from locations_rating 
    where attribute_id in (1,2,3) 
    group by location_id order by sum desc;

який повертається

 location_id | sum 
-------------+-----
          21 |  12
           3 |  11

Найближче, що я можу отримати з ORM:

Rating.objects.filter(
    attribute__in=attributes).annotate(
    acount=Count('location')).aggregate(Sum('score'))

Яка повертається

{'score__sum': 23}

тобто сума всіх, не згрупованих за місцем розташування.

Будь-який спосіб обійти це? Я міг би виконати SQL вручну, але скоріше ходив би через ORM, щоб все було послідовно.

Дякую



Відповіді:


136

Спробуйте це:

Rating.objects.filter(attribute__in=attributes) \
    .values('location') \
    .annotate(score = Sum('score')) \
    .order_by('-score')

3
мммм - анотувати не сукупно - чому це?
Гай Боуден,

51
aggregateпризначений для повного набору результатів, annotateдля окремих (згрупованих) рядків.
Bouke

хтось знає, як обійти 'dict' object has no attribute '_meta'такий QuerySet?
maciek

Привіт @Aamir, у мене схожа проблема, ти можеш поглянути на неї? посилання сюди
Ермір Бецирадж

Повертає щось на зразок[{"location": 53, "score": 100}, {"location": 54, "score": 104}]
Ірван

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.