我正在尝试使用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。
我出错的任何想法?
答案 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。否则贾斯汀的回答应该会很好。