1

我想每个类别选择一本书并获取每个类别中的书籍数量

我的模型:

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 分组,所以我得到了所有书籍的列表,根本没有分组。

4

3 回答 3

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"'
于 2013-07-29T09:48:36.513 回答
1

MySQL 文档

在标准 SQL 中,包含 GROUP BY 子句的查询不能引用选择列表中未在 GROUP BY 子句中命名的非聚合列。

这意味着在单个查询中实现您想要的唯一方法是使用OUTER JOIN语句。OUTER JOIN据我所知,Django ORM 不支持从表到自身的语句。

除了使用原始 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']
于 2013-07-29T11:44:00.910 回答
1

尝试这个:

Book.objects.values('category').annotate(total_messages=Count('title'))
于 2013-07-29T09:48:45.837 回答