【问题标题】:Querying hits per hour on Django timezone aware setup在 Django 时区感知设置上查询每小时点击次数
【发布时间】:2018-05-05 14:32:40
【问题描述】:

我是整个 Django 方面的新手,发现自己陷入了整个时区意识混乱。

问题

我想查询数据库以创建报告,例如:

Time of day | Clicks
--------------------
12 am       | 3
1 am        | 12
2 am        | 28
3 am        | 48
...

我希望这些显示基于创建事件的用户的时区,而不是系统的时区设置。

当前方法

给定以下模型(为避免混乱而进行了简化)并假设导入了正确的库。

class Event(models.Model):
    type = models.CharField()
    created = models.DateTimeField()
    user = models.CharField()

然后我在tests.py中创建了以下内容

def test_events_per_day(self):

# creates events in two timezones

    date = datetime(2017, 1, 13, 12, 0, 0, 0, pytz.timezone('Pacific/Auckland'))
    date2 = datetime(2017, 1, 13, 12, 0, 0, 0, pytz.timezone('UTC'))

    Event.objects.create(
        type='click',
        created=date.strftime('%Y-%m-%dT%H:%M:00.%f%z'),
        user = 'user 1'
    )

    Event.objects.create(
        type='click',
        created=date2.strftime('%Y-%m-%dT%H:%M:00.%f%z'),
        user = 'user 2'
    )

    event_per_day_count = Event.objects \
        .filter(type='click') \
        .annotate(day=TruncDay('created')) \
        .values('day') \
        .annotate(events=Count('user', distinct = True)) \
        .order_by('day')


    self.assertEquals(over_time.first().get('events'), 2)
    # FAIL: AssertionError: 1 != 2
    # PASS if I use the same date for both

当我查看数据库时,时区信息消失了,而且似乎都保存在 UTC (as the first line of the documentation states) 中。

我查看了规范化,但我不太明白如何使用它来修复它。在数据库中记录时区信息并随时转换似乎很昂贵。在绝望中,我什至尝试设置USE_TZ = False 看看会发生什么,Django 告诉我 MySQL 不喜欢那样。

如前所述,我仍然对它的工作原理有所了解,因此欢迎任何指针、cmets 或鼓励的话。

【问题讨论】:

  • 没有。我的问题是我不知道如何在忽略时区信息的情况下检索特定小时的所有事件。正如我所说,我想看看有多少人在上午 9 点创建了点击,但在用户时区,而不是在系统时区。

标签: python mysql django datetime timezone


【解决方案1】:

你应该可以通过指定the tzinfo argument to TruncDay得到你想要的:

通常由 pytz 提供的 tzinfo 子类可以传递以截断特定时区中的值。

所以:.annotate(day=TruncDay('created', tzinfo=pytz.timezone('Pacific/Auckland')))

【讨论】:

    最近更新 更多