当没有关系时,注释计数并返回零

问题描述 投票:1回答:2

鉴于以下关系:

class LicenseRequest:
    license_type = models.ForeignKey(LicenseType)
    created_at = models.DateField(default=now, editable=False)

class LicenseType:
    name = models.CharField(max_length=100)
    value = models.CharField(max_length=3, unique=True)

我想计算为每种许可证类型创建了多少请求。但是,由于我正在生成图形,因此在该特定时间段内,我必须在许可证类型中包含0(零)而没有任何许可证请求。

我试着做了here的建议,但它没有用。我只能从具有多个许可证请求的许可证类型中获取计数。

qs = LicenseType.objects.filter(
                Q(licenserequest__created_at__range=(start_date, end_date)) | Q(licenserequest__isnull=True)
            ).annotate(rel_count=Count('licenserequest__id'))

我可以找到另一种方法来实现这个目标,但我想知道我是否可以通过注释来实现。

我正在使用

django django-queryset
2个回答
2
投票

及更高版本中,Count对象具有filter参数,因此我们可以为此指定编码:

qs = LicenseType.objects.annotate(
    rel_count=Count(
        'licenserequest',
        filter=Q(licenserequest__created_at__range=(start_date, end_date))
    )
)
qs = LicenseType.objects.annotate(
    rel_count=Count(
        'licenserequest',
        filter=Q(licenserequest__created_at__range=(start_date, end_date))
    )
)

对于及以下,我们可以使用Sum(..)表达式的Case(..)

qs = LicenseType.objects.annotate(
    rel_count=Sum(Case(
        When(
            licenserequest__created_at__range=(start_date, end_date),
            then=1
        ),
        default=0,
        output_field=IntegerField()
    ))
)

2
投票
qs = LicenseType.objects.annotate(count=Count('licenserequest__id')
condition = Q(licenserequest__created_at__range=(start_date, end_date)) & Q(licenserequest__isnull=True)
qs = qs.annotate(Case(When(condition, then=F('count')), default=0, output_field=IntegerField())

这应该适用于您提供的模型描述。要执行后面的过滤器,您不能使用直接.filter(),而是使用Case / When .annotate()子句

© www.soinside.com 2019 - 2024. All rights reserved.