Django:选择热门/最受欢迎的文章

时间:2012-05-17 15:04:10

标签: python django orm

我有以下型号

class Article(models.Model):
    title = models.CharField(max_length=255, db_index=True)
    slug = UniqueSlugField(prepopulate_from='title', unique=True)
    favorited = models.ManyToManyField(to=User, blank=True)
    tags = TaggableManager()
    ...

class Vote(models.Model):
    article = models.ForeignKey(to=Article)
    voter = models.ForeignKey(to=User, related_name='voter')
    timestamp = models.DateTimeField(auto_now_add=True)
    ...

我使用以下代码行来按所选标记的降序获取热门文章

Vote.objects.filter(tags__in=[tag]).annotate(num_articles=Count('article')).order_by('-num_articles')

如何构建orm查询以通过Article.favorited的以下字段并基于Vote模型获取热门文章?

谢谢,

苏丹

2 个答案:

答案 0 :(得分:3)

为什么你会通过Vote模型获得“热门文章”?运行查询时,最终会得到Vote s的查询集。然后,您必须发出其他查询才能从中获取Article

您应该使用:

Article.objects.filter(tags=tag).annotate(vote_count=Count('vote')).order_by('-vote_count')

然后,你有一个Article s的正确查询集,你很高兴。

如果您想要收藏,请修改上述内容以使用user代替vote

Article.objects.filter(tags=tag).annotate(favorite_count=Count('user')).order_by('-favorite_count')

答案 1 :(得分:0)

使用加入

Article.objects.filter(favorited__in=[...]).annotate(
        vc=models.Count('vote')).order_by('-vc')

或者通常更快(更少的连接),但更复杂,更有限(不再是QuerySet,但通常不是一个大问题)子查询版本

qs = Article.objects.filter(favorited__in=[...])
top_votes = Vote.objects.filter(article__in=qs).values('article').annotate(
         vc=models.Count('pk')).values_list('article', 'vc').order_by('-vc')

# normally you may only want Top N
top_n_pks = tuple(pk for pk, vc in top_votes[:N])
tops = sorted(Article.objects.filter(pk__in=top_n_pks).order_by(),
         key=lambda x: top_n_pks.index(x.pk))