2

我在我的以下模型定义models.py

from django.db import models
class Blog(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

在我settings.py

TIME_ZONE = 'UTC'
USE_TZ = True

我想获得特定时区的时间。现在,如果我称它为Blog.objects.all()所有时间的UTC格式。但我想要请求的用户时区的时间。

我知道有可用的过滤器和标签。但正如我所做的那样,rest_framework我认为我需要能够在Queryset.

有什么帮助吗?

编辑:

到目前为止,我已经编写了这样的查询集

from django.utils import timezone
from django.db import models
Blog.objects.annotate(
    local_create_time = timezone.template_localtime(models.Expressionwrapper(models.F('created'), output_field=models.DateTimeField(), pytz.timezone('Europe/Madrid'))
)

它不会将数据转换Europe/Madrid为时区。但将数据输出到时UTC区。

所以我检查了timzone.template_localtime(value, use_tz=None)定义。

对我来说 use_tz 正在传递一个对象tzinfo,但是valueExpressionWrapper(F(created))

4

2 回答 2

0

在python中,您可以通过这种方式获取不同时区的时间:

from datetime import datetime
from pytz import timezone

time_Madrid=datetime.now(timezone('Europe/Madrid'))
time_UTC=datetime.now(timezone('UTC'))
time_GMT=datetime.now(timezone('Etc/GMT-3'))
于 2017-08-04T07:44:48.450 回答
0

一个很老的问题。但我来到这里遇到了类似的问题。虽然我的解决方案可能不适用于您的用例,但它可能。您的需求在问题中并不是 100% 明确的。

就我而言,因为我有一个任何地方都可以使用的网站(就像在网站中一样,因为这对所有网站都是如此),而且当地人可以用来管理当地事件(所以在当地时间),我还必须努力解决Django 中的时区。

现在我使用 Postgresql 作为后端,因此我的兴趣适用于该上下文。Postgresql 基本上以 UTC 存储所有日期时间。那是当我在 Python 代码中有一个本地时间并要求设置一个 Django 模型字段,然后在保存它时,时区信息仅用于转换为 UTC,然后丢失。

然后,当我使用 Django 读取该字段时,它是 UTC 格式的,我可以将其本地化到一个时区,但是什么时区呢?Django 中有一个活动时区,这很好,但实际上有三个时区是任何上下文的候选者:

  1. 网络服务器的时区。最不有趣,因为没有最终用户本身关心服务器在哪里。但最容易获得。

  2. 客户端的时区。我可以并且确实从客户端收集此信息,即在页面加载时的 JavaScript 中,我使用客户端的当前时区回调并记下会话(实际上我将其记录在用户会话数据中)。这确实很有趣,远远超过网络服务器的时区。

  3. 提交者的时区。现在我们在谈生意。这对我来说是最有趣的。因此,我创建了一个从霍巴特时间晚上 7 点开始的活动,而您正在使用马德里的网站,然后查看该活动,您会发现现在是晚上 7 点(即您看到的是霍巴特时间,活动创建者计划的时间)。

实现 3 个当然谓词:

  1. 提交者可以选择时区(我在登录提示中显示这个,默认情况下预先填充了客户端的时区)
  2. 我们将提交者的首选时区记录在事件中。

现在对于 1. 以上,您当然可以为每个事件提交提供一个选项,任何具有日期时间的表单字段您也可以提供一个时区选择器。对于我的需要,这是矫枉过正的。登录用户通常只想处理当地时间。但是探索远程数据很高兴在一天中的适当时间看到它(TZ 也会影响一天)。

我采用的方法如下:

  1. 任何具有 DateTimeField 的 Django 模型,在其后都有一个 TimeZoneField,其名称完全相同,但附加了“_tz”。这记录到 DateTimeField 的时区。

  2. 然后我构建了一个快速的自定义 Transformer:

from django.db.models import Transform, DateTimeField


class DateTimeLocal(Transform):
    lookup_name = 'local'

    def as_sql(self, compiler, connection):
        lhs, params = compiler.compile(self.lhs)
        dt = lhs  # has quotes like "table_name"."date_time"
        tz = lhs[:-1] + "_tz" + lhs[-1]  # Add _tz to field name
        return f"{dt} AT TIME ZONE {tz}", params


DateTimeField.register_lookup(DateTimeLocal)

并且可以像这样使用它:

Blog.objects.filter(created__local>someday)

那就是伪字段created__local现在可用(它是一个变换)。

问题是,如果您查看 Transform,它:

  1. as_sql. 我不知道它的便携性如何,并且怀疑它是否非常便携。

  2. 断言模型中是否存在created_tzTimeZoneField。

这里有一些帮助:https ://docs.djangoproject.com/en/4.0/howto/custom-lookups/

于 2022-02-28T05:23:58.827 回答