想象一下这个简单的模型:

class Expense(models.Model):
   price = models.DecimalField(decimal_places=2, max_digits=6)
   description = models.CharField(max_length=300)
   category = models.CharField(choices=ExpenseCategory.choices, max_length=20)
   created_at = models.DateField()

我正在努力获得本年度每category人每月price人的平均值.我的总体 idea 是:

sub = (
   Expense.objects.filter(created_at__year=date.today().year)
   .annotate(month=TruncMonth("created_at"))
   .values("month", "category")
   .annotate(total=Sum("price"))
   .order_by("month")
)
qs = Expense.objects.values("category").annotate(avg=Avg(Subquery(sub.values("total"))))

我基本上是想:

  1. 缩短created_at个月
  2. categorymonth分组
  3. prices加起来
  4. category个加prices

如果我真的喜欢:

for category in categories:
   sub.filter(category=category).aggregate(avg=Avg("total"))

推荐答案

你的问题可能比你想象的要简单.您目前try 的解决方案是:

  1. 截短created_at以获得月份
  2. categorymonth分组
  3. 总数prices
  4. 取每个类别总和的平均值

这样做的问题是将一个集合取为一个集合.让我们反过来思考你的问题(我们将在这里做一点数学).你想要一个类别的月平均价格,如果我们只考虑一个类别,而月平均价格是一个数组M[12],那么我们可以表示为:

(M[0] + M[1] + ... + M[11]) / 12

在月份匹配的情况下,M中的每个值都可以被视为prices的总和.如果我们认为P[12][]是一个二维数组,包含每个月的价格,我们可以将上述公式改写为:

(Sum(P[0]) + Sum(P[1] + ... + Sum(P[12])) / 12

进一步考虑一下,它只是一年中所有价格的总和除以12!这意味着您的查询可以简单地写为:

from django.db.models import ExpressionWrapper, FloatField, Sum, Value


qs = Expense.objects.filter(
    created_at__year=date.today().year
).values("category").annotate(
    avg=ExpressionWrapper(
        Sum("price") / Value(12), output_field=FloatField()
    )
)

Note:除以12意味着我们假设我们有全年的数据,这可能对今年不正确,所以我们应该除以适当的月数.我们可能还想过滤到上个月,以防我们没有明显进入本月.

Django相关问答推荐

Django为什么我的post.count_view递增2?

如何在 Django REST Framework API 响应中使用多标签过滤器?

有什么方法可以自动设置 Debug True Django application

在 django 中使用自定义 url 转换器传递 url 参数

Pymongo:搜索文档时忽略空输入值

如何在 ModelViewSet 逻辑中读取查询字符串值?

Django基于类的视图上的success_url的反向抱怨循环导入

使用基于类的 UpdateView 在 Django 中更新用户模型

可以在基于 Django 类的视图中设置实例变量吗?

将 XML 从 URL 解析为 python 对象

超过 1 个外键

Django - 来自 QuerySet 的唯一列表

Python Django:您正在使用 staticfiles 应用程序而没有设置 STATIC_ROOT 设置

Django - 一起为 2 个或更多字段创建唯一的数据库约束

获取 django 应用的绝对路径

Django 模型:delete() 未触发

如何测试 Django QuerySets 是否相等?

Django:DoesNotExist从何而来?

django-getlist()

左加入 Django ORM