Django按日期注释数据以获取空结果

Tia*_*Liu 5 python django orm django-annotate

假设我有一个对象模型A,它有一个名为created的字段,这是一个日期时间类型字段。

如果我使用注释来计算每天创建的A数,则可以使用

A.objects.annotate(date=Trunc('created', 'day', output_field=DateField()) ).values('date').order_by('date').annotate(count=Count('id'))
Run Code Online (Sandbox Code Playgroud)

之后,我可以得到结果,看起来像

[{date: '2018-07-22', count:1 }, {date: '2018-07-23', count:1 }, {date: '2018-07-25', count:1 }]
Run Code Online (Sandbox Code Playgroud)

但是,请注意,我错过了2018-07-24,因为它当天没有创建任何A. 有什么方法可以让结果包含{date: '2018-07-24', count:0 }在该查询集中吗?

Dmy*_*nko 0

我的 PostgreSQL 变体:

from datetime import date, timedelta
from django.db.models.functions import Trunc
from django.db.models.expressions import Value
from django.db.models import Count, DateField

# A is model

start_date = date(2022, 5, 1)
end_date = date(2022, 5, 10)

result = A.objects\
    .annotate(date=Trunc('created', 'day', output_field=DateField())) \
    .filter(date__gte=start_date, date__lte=end_date) \
    .values('date')\
    .annotate(count=Count('id'))\
    .union(A.objects.extra(select={
             'date': 'unnest(Array[%s]::date[])' %
                     ','.join(map(lambda d: "'%s'::date" % d.strftime('%Y-%m-%d'),
                                  set(start_date + timedelta(n) for n in range((end_date - start_date).days + 1)) -
                                  set(A.objects.annotate(date=Trunc('created', 'day', output_field=DateField())) \
                                               .values_list('date', flat=True))))})\
            .annotate(count=Value(0))\
            .values('date', 'count'))\
    .order_by('date')
Run Code Online (Sandbox Code Playgroud)