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

Django annotate data by date for empty result

提问人:Tiancheng Liu 提问时间:7/28/2018 更新时间:5/10/2022 访问量:1102

问:

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

如果我使用 annotate 来计算每天创建多少个 A,我可以使用

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

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

[{date: '2018-07-22', count:1 }, {date: '2018-07-23', count:1 }, {date: '2018-07-25', count:1 }]

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

python django orm django-annotate

评论

3赞 Giorgio 12/10/2018
你找到解决方案了吗?谢谢
0赞 Marek Naskret 6/28/2020
嗨,也许试试这个:stackoverflow.com/questions/52290430/......
1赞 DJ Ramones 1/5/2021
这回答了你的问题吗?Django + PostgreSQL:填充范围内缺失的日期
0赞 DJ Ramones 1/5/2021
@MarekNaskret答案不适用,因为该问题适用于存在相关模型的情况。(问题标题的“当没有关系时”部分具有误导性。此问题位于单个模型的上下文中,查询只能使用同一模型的属性。
0赞 Dakolas 9/19/2023
我想这就是你要找的 stackoverflow.com/questions/52290430/......

答:

0赞 Dmytro Ivashchenko 5/10/2022 #1

我的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')