2014-03-18 26 views
0

隨着車型:Django的查詢聚集訪問分組像這樣定義的所有領域

class Athlete(models.Model): 
    name = models.CharField() 

class Event(models.Model): 
    winner = models.ForeignKey(Athlete) 
    distance = models.FloatField() 

    type_choices = [('LJ', 'Long Jump'), ('HJ', 'High Jump')] 
    type = models.CharField(choices=type_choices) 

我想運行一個查詢挑選出一個Athlete贏得了所有事件,按類型分組。目前,我正在做它像這樣:

athlete = Athlete.objects.get(name='dave') 
events_by_type = Events.objects.values('type').annotate(Count('winner')).filter(winner=athlete) 

這給我的事件類型的詞典(短版本)和時代的運動員一直是冠軍的數量。然而,這就是它給我的。如果我想挖掘其中一個事件來尋找距離,甚至只是詳細的類型名稱,我不能。

我正在以正確的方式解決這個問題嗎?我如何獲得組合的事件,還可以訪問所有的字段?

回答

1

您沒有得到事件實例,因爲您正在使用方法查詢Event.objects。這將爲您提供僅用於指定字段的數據: https://docs.djangoproject.com/en/dev/ref/models/querysets/#values

使用Django ORM執行此類組不是直接的。建議的解決方案通常是:

q = Events.objects.filter(winner=athlete) 
q.query.group_by = ['type'] 
q.count() 

但我寧願用直接的python來做。也許類似

athlete = Athlete.objects.get(name='dave') 
events = Events.objects.filter(winner=athlete) 
won_per_type = defaultdict(list) 
for e in events: 
    won_per_type(e.type).append(e) 
+0

感謝您的回答。你能否詳述一下你爲什麼寧願用第二種方式做?性能影響是什麼? – Ferguzz

+0

如果您需要訪問模型實例,第二種方法更加明確和可讀,並且與數據庫相同的成本。如果你的運動員的事件列表是巨大的,這可能不是最好的選擇,我懷疑。後者也相當於當您在模板中進行分組時,Django自身執行的操作。https://docs.djangoproject.com/en/dev/ref/templates/builtins/#regroup – jminuscula