我有以下型号
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
模型获取热门文章?
谢谢,
苏丹
答案 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))