【问题标题】:Getting a count per hour for the past week获取过去一周每小时的计数
【发布时间】:2018-08-14 12:58:57
【问题描述】:

我有一个拍摄的照片模型。我正在使用 Javascript 构建过去 7 天的照片拍摄时间的热图。我每小时显示一次。

我的照片模型有一个时间戳 DateTime 字段。我如何制作这样的列表,显示过去一周每天每小时的照片总数?

javascript 需要这样的数组:

const heatmapDataSource = [
  [0, 0, 3],
  [6, 23, 3],
  ....
];

heatmapDataSource[0][0] 是星期几(今天(星期二)0, 上周星期三 (6) - 今天总是 0

heatmapDataSource[0][1] 是小时(0 == 24:00 和 23 == 23:00 等)

heatmapDataSource[0][2] 是该小时的计数值

希望这是有道理的!

到目前为止,我已经把这些放在一起作为开始计数:

    Photo.objects.annotate(
    hour=Trunc('timestamp', 'hour', output_field=DateTimeField())
).values('timestamp__hour', 'timestamp__day').annotate(photos=Count('id'))

输出:

<QuerySet [{'timestamp__hour': 10, 'timestamp__day': 10, 'photos': 8}, {'timestamp__hour': 12, 'timestamp__day': 13, 'photos': 1}]>

照片模特:

class Photo(models.Model):
    camera = models.ForeignKey(Camera, null=True, on_delete=models.PROTECT)
    image = models.ImageField()
    timestamp = models.DateTimeField(auto_now=True)

UDPATE

这就是我目前所拥有的,几乎就在那里..

import datetime as DT
today = DT.date.today()
week_ago = today - DT.timedelta(days=7)
from django.db.models.functions import ExtractWeekDay


Photo.objects.filter(timestamp__gte=week_ago).annotate(weekday=ExtractWeekDay('timestamp')).annotate(hour=Trunc('timestamp', 'hour', output_field=DateTimeField())).values('timestamp__hour', 'weekday').annotate(photos=Count('id'))

【问题讨论】:

  • 你能分享你写的代码,但不能为你解决问题吗?
  • 您应该查看queryset.annotate(hour=Trunc('datefield', 'hour'))regroup 以在您的模板中呈现它。 docs.djangoproject.com/en/2.0/ref/templates/builtins/#regroup
  • 谢谢,让我来做吧!
  • 请分享您的模型。
  • 我想我几乎已经回答了自己。我只需要对一周中的日子保持聪明,就可以将今天变成 0..

标签: python django


【解决方案1】:

首先我们需要对查询本身进行一些修复:__day 的范围为 1-31,这可能不是我们想要的。我们想要工作日,所以:

from django.db.models import Count
from django.db.models.functions import ExtractHour, ExtractWeekDay

qs = Photo.objects.annotate(
    hour=ExtractHour('timestamp'),
    day=ExtractWeekDay('timestamp')
).values('hour', 'day').annotate(
    photos=Count('id')
).order_by('hour', 'day')

接下来我们需要做一些后期处理:

from datetime import date
dow = date.today().isoweekday() + 1

result = [
    [(row['day'] - dow) % 7, row['hour'], row['photos']]
    for row in qs
]

这将产生一个 n×3 列表,然后可以通过 JSON 传输。

【讨论】:

  • 如何破解它以使今天总是 0(如工作日),然后返回 1 2 3 4 等?
  • 这样“明天”是6?
  • 嗯,不,它会倒退。昨天是 1
  • 是的,但是说还有 8 天之后,应该是 1 还是 8
  • 然后你可以用dow - row['day']替换row['day'] - dow(所以“反向”中的减法)。
猜你喜欢
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多