如何使用Django ORM按年份列出所有带文章计数的文章

时间:2010-10-19 13:20:28

标签: django django-models django-templates django-views

我正在尝试使用django ORM获取所有文章的年份列表,旁边有文章计数,例如:

2010(5篇)
2009年(4篇)
2008年(9篇文章)

我尝试了以下内容:

archive = Articles.objects.dates('created','year')。annotate(archive_count = Count('created'))

或:

archive = Articles.objects.values('created')。annotate(archive_count = Count('created'))

或:

archive = Articles.objects.values('created')。aggregate(archive_count = Count('created'))

最后一个给了我正确的计数,但是没有给我任何年份值,其他的给出了任何一个的混合,或者每行的archive_count被设置为1。

我出错的任何想法?

3 个答案:

答案 0 :(得分:5)

以下是在一个查询中执行此操作的方法:

Article.objects.extra(select={'year':"strftime('%%Y',created)"}).values('year').order_by().annotate(Count('id'))

请注意,您必须根据您的数据库替换strftime('%%Y',created)(我使用的是sqlite)。

答案 1 :(得分:2)

我不确定将数据库命中率保持在最低限度是您的主要目标。如果是这样,可能还有另一种我没有考虑过的方法。但乍一看,这看起来像你想要的:

archive={}
years = Article.objects.dates('created', 'year')
for year in years:
    archive[year.year] = Article.objects.filter(created__year=year.year).count()

然后你会得到一本字典{2010:5,2009:4,2008:9}。

答案 2 :(得分:1)

在一个理想的世界里,你可以写下:

archive = Articles.objects.values('created__year').annotate(archive_count=Count('created')).order_by()

获得您想要的结果。不幸的是,django不支持除精确字段名称之外的任何内容作为values()的参数

archive = Articles.objects.values('created').aggregate(archive_count=Count('created'))

无法工作,因为值('created')为您提供了'created'的所有唯一值的字典,其中包含的不仅仅是'year'。

如果您真的想通过单个ORM调用来执行此操作,则必须使用额外函数并完全编写自定义SQL。否则贾斯汀的回答应该会很好。