count和group by的Django等价物

2024-05-17 22:33:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个这样的模型:

class Category(models.Model):
    name = models.CharField(max_length=60)

class Item(models.Model):
    name = models.CharField(max_length=60)
    category = models.ForeignKey(Category)

我希望为每个类别选择项的计数(仅为计数),因此在SQL中,它将非常简单,如下所示:

select category_id, count(id) from item group by category_id

有没有相当于这样做的“Django方式”?或者纯SQL是唯一的选择?我熟悉Django中的count()方法,但是我不知道group by如何适合那里。


Tags: nameidsqlbymodelmodelscountgroup
3条回答

这里,正如我刚刚发现的,是如何使用Django 1.1聚合API来实现这一点:

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

因为我对Django 1.1中的分组是如何工作的有点困惑,所以我想在这里详细说明一下如何使用它。首先,重复迈克尔的话:

Here, as I just discovered, is how to do this with the Django 1.1 aggregation API:

from django.db.models import Count
theanswer = Item.objects.values('category').annotate(Count('category'))

还要注意,您需要from django.db.models import Count

这将只选择类别,然后添加名为category__count的注释。根据默认顺序,这可能是您所需要的全部,但如果默认顺序使用的字段不是category,则这将不起作用。这是因为排序所需的字段也被选中,并且使每一行都是唯一的,所以您不会按照自己的需要对内容进行分组。解决此问题的一个快速方法是重置顺序:

Item.objects.values('category').annotate(Count('category')).order_by()

这会产生你想要的结果。要设置可以使用的批注的名称,请执行以下操作:

...annotate(mycount = Count('category'))...

然后在结果中有一个名为mycount的注释。

其他关于分组的事情对我来说都很简单。一定要查看Django aggregation API以获得更详细的信息。

更新:完全ORM聚合支持现在包含在Django 1.1中。对于下面关于使用私有api的警告,这里描述的方法不再适用于Django的后1.1版本。我还没有深入了解原因;如果你在1.1或更高版本上,无论如何都应该使用真正的aggregation API。)

核心聚合支持在1.0中就已经存在了;它只是没有文档,不受支持,而且上面还没有友好的API。但在1.1版本到来之前,您仍然可以使用它(风险由您自己承担,并且完全知道query.group_by属性不是公共API的一部分,并且可能会更改):

query_set = Item.objects.extra(select={'count': 'count(1)'}, 
                               order_by=['-count']).values('count', 'category')
query_set.query.group_by = ['category_id']

如果您随后遍历查询集,则每个返回值都将是一个字典,其中包含一个“category”键和一个“count”键。

您不必在这里按计数排序,这只是为了演示它是如何完成的(它必须在.extra()调用中完成,而不是在queryset构造链的其他地方)。同样,你也可以说count(id)而不是count(1),但是后者可能更有效。

还要注意,在设置.query.group_by时,值必须是实际的数据库列名(“category_id”),而不是Django字段名(“category”)。这是因为您正在调整查询内部结构,使其处于一个所有内容都以DB术语而不是Django术语表示的级别。

相关问题 更多 >