2017-06-14 54 views
0

我想訂購我的查詢基於upvotes的數量,但我無法弄清楚如何做到這一點。這看起來太複雜了! (順便說一句我是過於複雜的東西?)基於最多upvotes排序查詢

所以這裏是我的models.py

class Activity(models.Model): 
    FAVORITE = 'F' 
    LIKE = 'L' 
    UP_VOTE = 'U' 
    DOWN_VOTE = 'D' 
    FOLLOW = 'W' 
    REPORT = 'R' 
    ACTIVITY_TYPES = (
     (FAVORITE, 'Favorite'), 
     (LIKE, 'Like'), 
     (UP_VOTE, 'Up Vote'), 
     (DOWN_VOTE, 'Down Vote'), 
     (FOLLOW, 'Follow'), 
     (REPORT, 'Report') 
    ) 

    user = models.ForeignKey(User) 
    activity_type = models.CharField(max_length=1, choices=ACTIVITY_TYPES) 
    date = models.DateTimeField(auto_now_add=True) 

    # Below the mandatory fields for generic relation 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey() 


class Entry(models.Model): 
    text = models.TextField(default='') 
    time_created = models.DateTimeField(auto_now=False, auto_now_add=True) 
    time_updated = models.DateTimeField(auto_now=True, auto_now_add=False) 
    created_by = models.ForeignKey(User, on_delete=models.CASCADE) 

    class Meta: 
     abstract = True 

class QuestionManager(models.Manager): 
    def by_topic(self, topic): 
     ... 
    def by_recent(self): 
     ... 
    def by_upvote_count(self): 
     return self.all().order_by('-upvotes')[:5]\ 
     .select_related('created_by','created_by__userprofile')\ 
     .prefetch_related('question_comments','question_comments__reply',) 


class Question(Entry): 

    objects = models.Manager() 
    get = QuestionManager() 

    activities = GenericRelation(Activity, related_query_name='questions') 

    def calculate_votes(self, type): 
     return self.activities.filter(activity_type=type).count() 

    up_votes = property(calculate_votes, 'U') 
    down_votes = property(calculate_votes, 'D') 

所以,我想要做的就是讓by_upvote_count返回前5 upvoted項目。

我發現django.db.modelsCOUNT()方法,但可以把它與我的設置工作,我想要做這樣的事情:

Question.objects.all().annotate(q = Count(activities__activity_type='U')).order_by('-q') 

但很明顯,這不起作用。

回答

1

你可以做這樣的事情

Model.objects.filter(activity_type='U').annotate(q_count=Count('activity_type')).order_by('-q_count')[:5] 
+0

這將排序他們的所有活動,但我想排序他們只是由Upvotes,downvotes,喜歡或... – arianhf

+0

嘗試編輯ans @arianhf – Exprator

+0

所以,你的答案類型的作品,但它不完全我想要的是。如果您將Count('activity_type')更改爲Count('activities__activity_type)和filter(activity_type ='U')來篩選(activities__activity_type ='U'),但是這會返回所有已投票的帖子並排除那些不會投票的帖子尚未得到滿意的答覆。 我在下面的答案包括這兩種類型,這就是我正在尋找的。 感謝您的幫助,非常感謝。 – arianhf

1

好了,讀了一堆的文章和計算器的一些問題後,我終於找到了工作的答案,這裏有雲:

from django.db.models import Case,When 
Question.objects.all()\ 
.annotate(upvotes=Count(
    Case(
     When(activities__activity_type='U', then=1) 
    ), distinct=True 
)).order_by('-upvotes')[:5] 

使用Case, and When您可以在查詢中執行條件。