使用django查询返回活动时区中的日期时间

时间:2015-10-20 22:23:51

标签: python django datetime django-queryset django-timezone

我正在尝试从表中检索最后n小时的行并在给定的时区中打印它们的日期时间,给出打印日期时使用的时区,我正在尝试使用activate来使django返回正确的日期时间时区,但它返回UTC日期。

这是我目前的代码:

min_time = datetime.datetime.now(link.monitor.timezone) - datetime.timedelta(hours=period)

timezone.activate(link.monitor.timezone)
rows = TraceHttp.objects.values_list('time', 'elapsed').filter(time__gt=min_time,link_id=link_id,elapsed__gt=0)

array = []
for row in rows:
    array.append((row[0].astimezone(link.monitor.timezone),row[1]))

我想避免使用astimezone函数并让Django为我这样做,有时候我对激活函数缺失了吗?

修改

以下是我的模型,因为您可以看到显示的时区保存在"监视器"模型:

class Link(models.Model):
   ...
   monitor = models.ForeignKey(Monitor)
   ...

class Monitor(models.Model):
    ...
    timezone = TimeZoneField(default='Europe/London')

class TraceHttp(models.Model):
    link = models.ForeignKey(Link)
    time = models.DateTimeField()
    elapsed = models.FloatField()

3 个答案:

答案 0 :(得分:2)

经过一些研究后,我注意到Django总是将日期时间作为UTC返回,并且您可以通过使用datetime.astimezone(时区)方法或激活某个时区来在正确的时区解释它们。

django活动函数只是改变了日期时间在模板上呈现的方式,但实际上并没有定位时区。

答案 1 :(得分:2)

如果您发现自己循环执行dt_value.astimezone(tzifo)from django.db.models.functions import Trunc, TruncDate qs = MyModel.objects.filter(...).values( 'dtime', ..., dtime_at_my_tz=Trunc('dtime', 'second', tzinfo=yourtz), date_at_my_tz=TruncDate('dtime', tzinfo=yourtz), month=TruncDate(Trunc('dtime', 'month', tzinfo=yourtz)), quarter=TruncDate(Trunc('dtime', 'quarter', tzinfo=yourtz)) ) 数百万次以计算时区中的当前日期,则可能是从1.10开始的最佳方法<= django.VERSION <= 2.1是使用django.db.models.functions.Trunc和相关函数,即使用查询集,如:

TruncDate

这将返回正确的时区中的日期时间或日期。您可以将其他Trunc *函数用作速记。如果您只需要datetime.date s,则timezone.localtime(ts)尤其有用

这会将日期计算卸载到数据库中,通常会大大减少代码复杂性并提高速度(在我的情况下,超过650万的$push贡献了25%的CPU时间)

答案 2 :(得分:0)

您可以使用Django.utils中的now()函数,但是,您需要在设置中设置两个变量。 USE_TZ和TIME_ZONE,第一个用于true,另一个用于默认时区,用于生成日期时间。 您可以在django文档here

中查看更多信息