python - Django 每天汇总记录数

标签 python django orm

我有一个正在执行一些日志记录的 Django 应用程序。我的模型如下所示:

class MessageLog(models.Model):
    logtime = models.DateTimeField(auto_now_add=True)
    user = models.CharField(max_length=50)
    message = models.CharField(max_length=512)

我想做的是获取一周中每天记录的平均消息数,以便我可以查看哪些天最活跃。我设法编写了一个查询来提取每天的消息总数,即:

for i in range(1, 8):
    MessageLog.objects.filter(logtime__week_day=i).count()

但是我在计算查询中的平均值时遇到了问题。我现在拥有的是:

for i in range(1, 8):
    MessageLog.objects.filter(logtime__week_day=i).annotate(num_msgs=Count('id')).aggregate(Avg('num_msgs'))

出于某种原因,这每天都会返回 1.0。我查看了它生成的 SQL,它是:

SELECT AVG(num_msgs) FROM (
SELECT 
`myapp_messagelog`.`id` AS `id`, `myapp_messagelog`.`logtime` AS `logtime`, 
`myapp_messagelog`.`user` AS `user`, `myapp_messagelog`.`message` AS `message`, 
COUNT(`myapp_messagelog`.`id`) AS `num_msgs` 
FROM `myapp_messagelog` 
WHERE DAYOFWEEK(`myapp_messagelog`.`logtime`) = 1 
GROUP BY `myapp_messagelog`.`id` ORDER BY NULL
) subquery

我认为问题可能出在 GROUP BY id 上,但我不太确定。有人有什么想法或建议吗?提前致谢!

最佳答案

您列出的查询总是给出 1 的原因是因为您没有按日期分组。基本上,您已要求数据库获取属于一周中指定日期的 MessageLog 行。对于每一行,计算它有多少个 id(总是 1)。然后取所有这些计数的平均值,这当然也是 1。

通常,您需要使用 values子句在 annotateaggregate 部分之前对 MessageLog 行进行分组。但是,由于您的 logtime 字段是日期时间而不仅仅是日期,我不确定您是否可以直接使用 Django 的 ORM 来表达它。您绝对可以使用 extra 子句来完成它,如图所示 here .或者,如果您愿意,可以在 SQL 中声明一个 View ,其中包含您喜欢的聚合和平均数学,并为其声明一个非托管模型,然后正常使用 ORM。

因此,extra 字段用于获取实际每天的记录总数,但不处理计算注释的平均值的聚合。我认为这可能已经从您必须使用原始 SQL 查询的模型中充分抽象出来,或者至少我找不到任何可以让它在一次调用中工作的东西。

也就是说,您已经知道如何在一个简单的查询中获取每个工作日的记录总数,如您的问题所示。

此查询将告诉您在给定工作日有多少个不同的日期记录:

MessageLog.objects.filter(logtime__week_day=i).dates('logtime', day').count()

因此,您可以改用 Python 进行平均数学运算,这可能比尝试正确使用 SQL 更简单。

或者,此查询将在一个查询中而不是 for 循环中为您获取所有工作日的原始消息数:

MessageLog.objects.extra({'weekday': "dayofweek(logtime)"}).values('weekday').annotate(Count('id'))

但我无法得到一个很好的查询来为您提供每个工作日的不同日期的计数 - 日期查询集失去了处理注释调用的能力,并且无法通过 extra 值似乎也不起作用。

这出奇地棘手,因为它不是那么难的 SQL 表达式。

关于python - Django 每天汇总记录数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16847601/

相关文章:

python - 使用 Python 写入文本文件时出现编码问题

python - 如何在 Google Colab 中引用共享文件和文件夹?

python - 使用 Python passlib 创建密码

activerecord - 如何在 Yii 中使用 dataprovider 获取连接表的所有列?

java - JPA2 唯一约束 : do I really need to flush?

python - 将相关数据帧转换为字典 {key = (sample_x,sample_y), value = correlation}

python - 基于 Django 模型内部方法的计算字段

python - Django,形式 is_valid() 始终为 false

python - 获取2个日期之间的表数据django python

python - SQLALchemy 动态 filter_by