以下是我的型号:
class Project(models.Model):
name = models.CharField(max_length=1000, null=True, blank=True)
date_created = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=1000, null=True, blank=True)
状态字段有大约5个不同的选项(赢得、丢失、打开、挂起、取消(。
我需要知道如何在给定的时间范围查询中获得每个月x状态的项目数量。
我能够使用以下注释获得正确的数据形状,但由于某种原因,给定的输出在一个月内为每个找到的状态提供一个对象。例如,如果存在至少1";赢得";和1〃;打开";在同一个月找到的项目中,两个单独的对象将在同一月份返回。此外,此处的状态选项是硬编码的,如果添加了新状态,则需要对其进行修改。
queryset = list(opps.annotate(
month=TruncMonth('date_created'),
).values('month').annotate(
total=Count('id'),
Win=Count('id', filter=Q(status='Win')),
Loss=Count('id', filter=Q(status='Loss')),
Open=Count('id', filter=Q(status='Open')),
Dormant=Count('id', filter=Q(status='Dormant')),
Pending=Count('id', filter=Q(status='Pending')),
Cancelled=Count('id', filter=Q(status='Cancelled')),
))
这是我当前输出的一个示例。
[{'month': datetime.datetime(2022, 5, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'total': 1, 'Win': 0, 'Loss': 1, 'Open': 0, 'Dormant': 0, 'Pending': 0, 'Cancelled': 0}
{'month': datetime.datetime(2022, 5, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'total': 1, 'Win': 0, 'Loss': 1, 'Open': 0, 'Dormant': 0, 'Pending': 0, 'Cancelled': 0}
{'month': datetime.datetime(2022, 5, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'total': 1, 'Win': 0, 'Loss': 0, 'Open': 1, 'Dormant': 0, 'Pending': 0, 'Cancelled': 0}
{'month': datetime.datetime(2022, 6, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='UTC')), 'total': 1, 'Win': 0, 'Loss': 0, 'Open': 1, 'Dormant': 0, 'Pending': 0, 'Cancelled': 0}]
如果您的Model没有通过Meta
类定义排序,则必须在第二次调用annotate
之前指定排序。
queryset = list(opps
.annotate(month=TruncMonth('date_created'))
.order_by('month') # <== this is necessary for the correct results
.values('month')
.annotate(total=Count('id'),
Win=Count('id', filter=Q(status='Win')),
Loss=Count('id', filter=Q(status='Loss')),
Open=Count('id', filter=Q(status='Open')),
Dormant=Count('id', filter=Q(status='Dormant')),
Pending=Count('id', filter=Q(status='Pending')),
Cancelled=Count('id', filter=Q(status='Cancelled'))))