我想为每个类别选择一本书,并计算每个类别的书籍数量
我的模特:
class Book(models.Model):
title = models.CharField(max_length=100)
category = models.CharField(max_length=100)
SQL应该类似于:
SELECT title, COUNT(*) as total FROM book GROUP BY category
我试过使用注释方法
Book.objects.annotate(total_messages=Count('category'))
但它按book.id分组,所以我得到了所有书籍的清单,根本没有分组。
答案 0 :(得分:2)
如果要指定分组字段,则应使用values():
Book.objects.values('category').annotate(total_messages=Count('title'))
这是它产生的查询:
>>> Book.objects.values('category').annotate(total_messages=Count('title')).query.__str__()
Out[11]: u'SELECT "my_app_book"."category", COUNT("my_app_book"."title") AS "total_messages" FROM "my_app_book" GROUP BY "my_app_book"."category"'
答案 1 :(得分:1)
试试这个:
Book.objects.values('category').annotate(total_messages=Count('title'))
答案 2 :(得分:1)
在标准SQL中,包含GROUP BY子句的查询不能引用选择列表中未在GROUP BY子句中命名的非聚合列。
这意味着在单个查询中实现所需内容的唯一方法是使用OUTER JOIN
语句。据我所知,Django ORM不支持从表到自身的OUTER JOIN
语句。
除了使用原始SQL语句之外,获得所需内容的唯一方法(包含该书类别中书籍数量的书籍列表)是使用2个单独的查询并在Python中处理它们。
qs = Book.objects.values('category').annotate(count=Count('id'))
count = dict([(x['category'], x['count']) for x in qs])
books = Book.objects.all()
for book in books:
book.category_count = count['category']