基于大多数upvotes订购查询

时间:2017-06-14 10:21:33

标签: python django django-queryset

我想根据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个赞成项目。

我找到 django.db.models Count()方法,但可以让它与我的设置一起使用,我想做这样的事情:

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

但显然这不起作用。

2 个答案:

答案 0 :(得分:1)

你可以做这样的事情

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

答案 1 :(得分:1)

好的,所以在阅读了一堆文章和stackoverflow中的一些问题之后,我终于找到了一个有效的答案,在这里:

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,您可以在查询中执行条件。