django在查询中计算相同字段值的最有效方法

时间:2010-08-31 06:05:23

标签: django django-models django-queryset

让我们说如果我的模型有很多字段,但我只关心一个字段。让我们说charfield可以是任何东西,所以我不知道可能的值,但我知道值经常重叠。所以我可以有20个带有“abc”的对象和带有“xyz”的10个对象,或者我可以有50个带有“def”的对象和带有“stu”的80个对象,我有40000没有重叠,我真的不在乎。

如何有效地计算对象?我想要归还的是:

{'abc':20,'xyz':10,'other':10,000}

或类似的东西,没有进行大量的SQL调用。

编辑:

我不知道是否有人会看到这个因为我编辑的时间有点晚了,但是......

我有这个型号:

class Action(models.Model):
    author = models.CharField(max_length=255)
    purl = models.CharField(max_length=255, null=True)

从答案来看,我已经这样做了:

groups = Action.objects.filter(author='James').values('purl').annotate(count=Count('purl'))

但是...

这就是群体:

{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "waka"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "mora"},{"purl": "lora"}

(我只是用虚拟值填充了purl)

我想要的是

{'waka': 4, 'mora': 5, 'lora': 1}

希望有人会看到这个编辑...

编辑2:

显然我的数据库(BigTable)不支持Django的聚合函数,这就是我遇到所有问题的原因。

4 个答案:

答案 0 :(得分:74)

你想要类似“count ... group by”的东西。您可以使用django的ORM的聚合功能执行此操作:

from django.db.models import Count

fieldname = 'myCharField'
MyModel.objects.values(fieldname)
    .order_by(fieldname)
    .annotate(the_count=Count(fieldname))

关于此主题的先前问题:

答案 1 :(得分:16)

这称为聚合,Django supports it directly

您可以通过在一组数据库调用中过滤您想要计算的值,获取值列表并计算它们来获得您的确切输出:

from django.db.models import Count
MyModel.objects.filter(myfield__in=('abc', 'xyz')).\
        values('myfield').annotate(Count('myfield'))

答案 2 :(得分:7)

您可以在查询集上使用Django的Count aggregation来完成此任务。像这样:

from django.db.models import Count
queryset = MyModel.objects.all().annotate(count = Count('my_charfield'))
for each in queryset:
    print "%s: %s" % (each.my_charfield, each.count)

答案 3 :(得分:1)

除非您的字段值始终保证在特定情况下,否则在执行计数之前对其进行转换可能很有用,例如“Apple'和' Apple'将被视为相同。

from django.db.models import Count
from django.db.models.functions import Lower

MyModel.objects.annotate(lower_title=Lower('title')).values('lower_title').annotate(num=Count('lower_title')).order_by('num')