Django ile VE toplanmasına göre gruplama


83

ORM aracılığıyla yapmak istediğim oldukça basit bir sorgum var, ancak bunu çözemiyorum ..

Üç modelim var:

Konum (bir yer), Nitelik (bir yerin sahip olabileceği bir özellik) ve Derecelendirme (aynı zamanda bir puan alanı içeren bir M2M 'ila' modeli)

Bazı önemli özellikler seçmek ve konumlarımı bu özelliklere göre sıralamak istiyorum - yani, seçilen tüm özelliklere göre daha yüksek toplam puan = daha iyi.

İstediğimi elde etmek için aşağıdaki SQL'i kullanabilirim:

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

hangi döner

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

ORM ile alabileceğim en yakın şey:

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

Hangi döner

{'score__sum': 23}

yani, konuma göre gruplandırılmamış tümünün toplamı.

Bunun etrafında herhangi bir yolu var mı? SQL'i manuel olarak çalıştırabilirdim, ancak işleri tutarlı tutmak için ORM üzerinden gitmeyi tercih ederim.

Teşekkürler



Yanıtlar:


136

Bunu dene:

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

3
hmmm - not toplama değil - bu neden?
Guy Bowden

51
aggregateannotatetek tek (gruplanmış) satırlar için tam sonuç kümesi içindir.
Bouke

'dict' object has no attribute '_meta'Böyle bir QuerySet ile nasıl geçici çözüm bulunacağını bilen var mı?
maciek

Merhaba @Aamir, benim de benzer bir sorunum var, bir bakabilir misin? link-here
Ermir Beqiraj

[{"location": 53, "score": 100}, {"location": 54, "score": 104}]
Şuna

38

Bunu deneyebilir misin?

Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.