Django 用空值注释字段

Django annotating fields with null values

我有 Demand 个对象的列表,这些对象具有 allocated 字段,可以是 null 或具有名称(表示此需求的分配)。

我使用注释计算每个团队的 allocated/unallocated 个数字:

Demand.objects.filter(project=project).values('team').annotate(
            unallocated=Count('allocated', filter=Q(allocated__isnull=True)),
            allocated=Count('allocated', filter=Q(allocated__isnull=False))
        )

奇怪的是 allocated 注释的数字正确显示,但 unallocated 的数字始终为零。

例如:

list(Demand.objects.filter(project=project).values('allocated', 'team'))

结果如下:

[{'allocated': None, 'team': 'Design'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Delivery'},
{'allocated': None, 'team': 'Product'}]

但是注释只有这个:

<QuerySet 
[{'team': 'Delivery', 'unallocated': 0, 'allocated': 0},
{'team': 'Design', 'unallocated': 0, 'allocated': 0},
{'team': 'Engineering', 'unallocated': 0, 'allocated': 0},
{'team': 'Product', 'unallocated': 0, 'allocated': 0}]>

我是不是做错了或者可能是一个错误?

这是因为 Count(…) [Django-doc] 不算 NULL,这就是 SQL 指定 COUNT 聚合如何工作的方式:它不考虑 NULL值(例如 AVG 也是如此)。但是您可以改为计算主键,例如:

from django.db.models import Count, Q

Demand.objects.filter(project=project).values('team').annotate(
    unallocated=Count(<strong>'pk'</strong>, filter=Q(allocated=None)),
    allocated=Count('allocated', filter=Q(allocated__isnull=False))
).order_by('team')

因此,您还可以将allocated简化为:

from django.db.models import Count, Q

Demand.objects.filter(project=project).values('team').annotate(
    unallocated=Count(<strong>'pk'</strong>, filter=Q(allocated=None)),
    allocated=Count('allocated')
).order_by('team')