2014-01-08 33 views
0

我有一定數量的ob主題和用戶。用戶可以投票選擇一個或多個主題。我想按照清除順序顯示按票數排序的前10位主題。顯示與ManyToMany關係的排序列表

事實上,我發現了一種工作方式,但我在問自己是否有更合適的方法來做到這一點。

我開始用型號:

class Subject(models.Model): 
    text = models.TextField() 

class User(models.Model): 
    name = models.CharField(max_length=64) 
    subject = models.ManyToManyField(Subject) 

現在我可以鍵入:

Subject.user_set.all() 

,我會得到誰投了贊成票爲主題的用戶。

現在我想列出一個列表視圖,前10個主題將按顯示的票數排序。 所以我添加了一個類的方法,以主題類:

class Subject(models.Model): 
    text = models.TextField() 

    @staticmethod 
    def by_votes(): 
     myList = list(Subject.objects.all()) 
     return sorted(myList, key=lambda s: s.user_set.count(), reverse=True)[:10] 

,並定義了基於類的觀點:

class SubjectListView(ListView): 
    model = Subject 
    template_name = "subject_list.html" 
    context_object_name = "subject_list" 
    queryset = Subject.by_votes() 

裏面居然效果很好。 但我在文檔Manager和QuerySet類中看到,不幸的是我不太明白如何使用它們(定義自定義的)來獲得我正在查找的內容(不涉及原始SQL查詢)。

我有點害怕,因爲我用了一個列表我能碰上有大量的個體記憶問題。 你會說什麼,它會更適合使用自定義管理器或查詢集,不會? 如果是,該怎麼辦?

還有其他想法嗎?

謝謝! 彼得

回答

1

無需定製經理或原料這裏SQL,只是聚集。

from django.db.models import Count 
Subject.objects.annotate(user_count=Count('user').order_by('-user_count')[:10] 
+0

非常感謝! – Bingo

1

我是相當新的,但我解決了類似的問題,這一點:

Subject.objects.all().annotate(count=Count('user')).order_by('-count')[:10] 

Aggregation Doc

+0

謝謝!我將閱讀關於聚合的這篇文檔! – Bingo