Cách nhóm theo VÀ tổng hợp với Django


82

Tôi có một truy vấn khá đơn giản mà tôi muốn thực hiện thông qua ORM, nhưng không thể tìm ra ..

Tôi có ba mô hình:

Vị trí (một địa điểm), Thuộc tính (thuộc tính mà một địa điểm có thể có) và Xếp hạng (mô hình M2M 'thông qua' cũng chứa trường điểm)

Tôi muốn chọn một số thuộc tính quan trọng và có thể xếp hạng vị trí của mình theo các thuộc tính đó - tức là tổng điểm cao hơn trên tất cả các thuộc tính đã chọn = tốt hơn.

Tôi có thể sử dụng SQL sau để có được những gì tôi muốn:

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

cái nào trả về

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

Điều gần nhất tôi có thể nhận được với ORM là:

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

Cái nào trả về

{'score__sum': 23}

tức là tổng của tất cả, không được nhóm theo vị trí.

Bất kỳ cách nào xung quanh điều này? Tôi có thể thực thi SQL theo cách thủ công, nhưng muốn thực hiện thông qua ORM để giữ mọi thứ nhất quán.

Cảm ơn



Câu trả lời:


135

Thử đi:

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

3
hmmm - chú thích không tổng hợp - tại sao vậy?
Guy Bowden

51
aggregatelà cho tập kết quả hoàn chỉnh, annotatecho các hàng riêng lẻ (được nhóm lại).
Bouke

có ai biết cách giải quyết 'dict' object has no attribute '_meta'với QuerySet như vậy không?
maciek,

Chào bạn @Aamir, mình cũng gặp vấn đề tương tự, bạn có thể xem qua được không? link-here
Ermir Beqiraj

Trả lại một cái gì đó giống như[{"location": 53, "score": 100}, {"location": 54, "score": 104}]
Irvan

38

Bạn có thể thử điều này.

Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.