2017-03-09 52 views
0

我已經實現了我想要的,但我不相信這是最好的方法。這是我的模型:這可以通過聚合來實現嗎?

class foo(models.Model): 
    user = models.ForeignKey(User) 
    rate = models.PositiveSmallIntegerField(default = 3) 
    rate1 = models.PositiveSmallIntegerField(default = 3) 
    rate2 = models.PositiveSmallIntegerField(default = 3) 

這是我的看法:

sum = {} 
bad_rating = None 
rate = foo.objects.values('user').distinct().annotate(r=Avg("rate"), r1 = Avg("rate1"), r2= Avg("rate2")) 
for r in rate: 
    sum[r['user']]=r['r']+r['r1']+r['r2'] 
bad_rating = sorted(sum.items(), key=operator.itemgetter(1)) 

基本上,我得到的raterate1rate2平均由不同的用戶進行分組。一旦我獲得了與不同用戶關聯的這三個字段的平均值,我想將它們加在一起,並保持用戶關聯。

在我的情況下,我有一個開始的查詢集,然後我將它存儲在一個字典中,然後我將它存儲在一個tupple列表中(因爲它允許我對它進行排序並獲得最低評分或最高評分) 。

是否有可能通過Django Queryset和聚合實現相同的結果?

在例如: 我的QuerySet結果:

<QuerySet [{'r': 1.0, 'r2': 3.0, 'user': 16, 'r3': 5.0}, {'r': 4.333333333333333, 'r2': 2.1666666666666665, 'user': 17, 'r3': 5.0}, {'r': 2.0, 'r1': 2.0, 'user': 18, 'r2': 2.0}]> 

相反,我想這將產生以下結果的查詢集:

<QuerySet [{16: 5.4}, {17: 3.5}, {18: 4.0}]> 

16是用戶ID和5.4爲avg(rate)+avg(rate1)+avg(rate2)

+1

也許它可以做成一個[查詢表達式](https://docs.djangoproject.com/en/1.10/ref/models/expressions/)?我想知道'F()'是否可以接受像'Avg'這樣的其他表達式作爲參數。 – 9000

+0

@ 9000感謝您的指導,如果我管理,我會給它一個嘗試和發佈答案。 –

回答

0

基於@ 9000評論我設法解決這個問題:

rate = foo.objects.values('user').distinct().annotate(r=Avg("rate"), r1= Avg("rate1"), r2= Avg("rate2")).annotate(a = F('r')+F('r1')+F('r2')).order_by('a')[:5] 

我現在唯一的問題是,它返回用戶的ID,這是有用的,但它是,如果它更方便返回的用戶,所以我可以直接在模板中使用它。

謝謝,

相關問題