Django 用按日期分组的百分比注释queryset

Django 用按日期分组的百分比注释queryset,django,python-3.x,django-models,django-orm,django-annotate,Django,Python 3.x,Django Models,Django Orm,Django Annotate,假设我有以下模型: class Order(models.Model): category = models.CharField(max_length=100, choices=CATEGORY_CHOICES, default=DEFAULT_CHOICE) created_at = models.DateTimeField(auto_now_add=True) 我需要在订单查询集上标注每个类别按月份分组的百分比(基于在字段创建的)。我设法写了一个查询来统计每个订单按月分组:

假设我有以下模型:

class Order(models.Model):
    category = models.CharField(max_length=100, choices=CATEGORY_CHOICES, default=DEFAULT_CHOICE)
    created_at = models.DateTimeField(auto_now_add=True)
我需要在
订单
查询集上标注每个
类别
按月份分组的百分比(基于在字段创建的
)。我设法写了一个查询来统计每个
订单
按月分组:

orders_per_month = (Order.objects
    .annotate(month=TruncMonth('created_at'))
    .values('month')
    .annotate(count=Count('id'))
    .order_by('month')
    .values('month', 'count')
)
orders_per_month = (Order.objects
    .annotate(month=TruncMonth('created_at'))
    .values('month', 'category')
    .distinct()
    .annotate(month_total=Window(
        expression=Count('id'),
        partition_by=[F('month')],
    ))
    .annotate(month_category=Window(
        expression=Count('id'),
        partition_by=[F('month'), F('category')],
    ))
    .annotate(percentage=ExpressionWrapper(
        F('month_category') * 100.0 / F('month_total'),
        output_field=FloatField()
    ))
    .values('month', 'percentage', 'category')
)
仅将最后一个
.values()
更改为
.values('month'、'category'、'count')
,我可以将计数按
类别和
月份进行分组

是否可以使用Django的ORM获得每个
类别的百分比?例如,如果我有以下数据:

MONTH | CATEGORY
Jan   | 'A'
Jan   | 'B'
Feb   | 'A'
我想得到类似的东西:

[
    (Jan, 'A', 0.5),
    (Jan, 'B', 0.5),
    (Feb, 'A', 1),
]
提前感谢。

正如@ac2001在评论中所建议的那样,使用Django的,我设法得到了我需要的东西

使用示例模型,假设我希望每个
类别的百分比按月份分组:

orders_per_month = (Order.objects
    .annotate(month=TruncMonth('created_at'))
    .values('month')
    .annotate(count=Count('id'))
    .order_by('month')
    .values('month', 'count')
)
orders_per_month = (Order.objects
    .annotate(month=TruncMonth('created_at'))
    .values('month', 'category')
    .distinct()
    .annotate(month_total=Window(
        expression=Count('id'),
        partition_by=[F('month')],
    ))
    .annotate(month_category=Window(
        expression=Count('id'),
        partition_by=[F('month'), F('category')],
    ))
    .annotate(percentage=ExpressionWrapper(
        F('month_category') * 100.0 / F('month_total'),
        output_field=FloatField()
    ))
    .values('month', 'percentage', 'category')
)

欢迎您提出进一步简化的建议。

您了解了吗?您应该查看Windows功能。可以使用分区参数进行计算。(1) 窗口按月分区并计数,(2)按月分区并分类并计数,(3)划分步骤1和步骤2。如果有帮助,请告诉我。