2015-10-16 147 views
0

您想提取一段時間內有關重複的呼叫統計。Django queryset多個聚合

實施例:

class Call(models.Model): 
    when_start = models.DateTimeField() 
    when_end = models.DateTimeField() 
    caller = models.CharField() 
    dnis = models.CharField() 

我應該得到這樣的:

result = {4: 1, 3: 3, 2: 4, 1: 1} 

詳情:

  • 4:1 => 1人稱爲4次
  • 3:3 = > 3人叫3次
  • 2:4 => 4人稱爲2倍
  • 1:稱爲1 => 1人1次

我試圖與此查詢集,但我由呼叫者獲得結果:

Call.objects.filter(when_start__range=(dt_start, dt_end)).values('caller').annotate(caller_count=Count('caller')).order_by('-caller_count') 

[{'caller_count': 4, 'caller': u'Mr X'}, 
{'caller_count': 3, 'caller': u'Mr Y'}, 
{'caller_count': 3, 'caller': u'Mr T'}, 
{'caller_count': 3, 'caller': u'Mr E'}, 
{'caller_count': 2, 'caller': u'Mr O'}, 
{'caller_count': 2, 'caller': u'Mr M'}, 
{'caller_count': 2, 'caller': u'Mr P'}, 
{'caller_count': 2, 'caller': u'Mr B'}, 
{'caller_count': 1, 'caller': u'Mr N'}] 

所以我必須添加此代碼以獲得結果:

result = {} 

for data in calls: 
    if data['caller_count'] not in result: 
     result[data['caller_count']] = 1 
    else: 
     result[data['caller_count']] += 1 

是否有可能直接使用一個查詢集獲得此結果?

+0

我不認爲這是可能的,但你可以使用'defaultdict(INT)'來簡化你的for循環。它不會那麼糟糕,因爲理想情況下,聚合結果的數量遠小於原始對象數量。 –

回答

0

你試過下一步:

Call.objects.filter(when_start__range=(dt_start, dt_end)) 
      .values('caller').annotate(caller_count=Count('caller')) 
      .order_by('-caller_count').annotate(Count('caller_count')) 
+0

是的:'FieldError:無法計算Count('caller_count'):'caller_count'是一個聚合 –