Django 如何使TimeField时区意识到?
有时,您需要从用户处收集时间而不收集相关日期。例如,如果用户正在配置每天同时运行的重复事件。Django的Django 如何使TimeField时区意识到?,django,Django,有时,您需要从用户处收集时间而不收集相关日期。例如,如果用户正在配置每天同时运行的重复事件。Django的TimeField不使用时区。然而,在这种特殊情况下(可能在任何时候你自己记录时间),时区是一个重要因素。那么,您如何存储时区感知时间呢?答案是您没有。要使时间具有时区意识,它必须有一个与之关联的日期。想想夏令时。。。我的解决方案是在模型上使用DateTimeField,并覆盖表单,如下所示: # Model class MyModel(models.Model): time_of_
TimeField
不使用时区。然而,在这种特殊情况下(可能在任何时候你自己记录时间),时区是一个重要因素。那么,您如何存储时区感知时间呢?答案是您没有。要使时间具有时区意识,它必须有一个与之关联的日期。想想夏令时。。。我的解决方案是在模型上使用DateTimeField
,并覆盖表单,如下所示:
# Model
class MyModel(models.Model):
time_of_day = models.DateTimeField()
# Form Fields
from django.forms.util import from_current_timezone
from django.forms.util import to_current_timezone
from django.utils import timezone
class TzAwareTimeField(forms.fields.TimeField):
def prepare_value(self, value):
if isinstance(value, datetime.datetime):
value = to_current_timezone(value).time()
return super(TzAwareTimeField, self).prepare_value(value)
def clean(self, value):
value = super(TzAwareTimeField, self).to_python(value)
dt = to_current_timezone(timezone.now())
return dt.replace(
hour=value.hour, minute=value.minute,
second=value.second, microsecond=value.microsecond)
# Forms
class MyForm(forms.ModelForm):
time_of_day = TzAwareTimeField()
这是未经测试和不完整的:
class TimeFieldWithZone(TimeField):
def db_type(self, connection):
if (connection.settings_dict['ENGINE'] ==
'django.db.backends.postgresql_psycopg2'):
return 'time with time zone'
raise Exception('Unsupported database type')
def get_db_prep_value(self, value, *args, **kwargs):
try:
return super(TimeFieldWithZone, self).get_db_prep_value(
value, *args, **kwargs)
except ValueError:
return six.text_type(value)
这将使用Postgres的时区数据类型。如果您以“HH:MM:SS.mmmmmm+HH:MM”格式向其传递一个字符串,并且现在使用auto_将尝试节省一段时间(不确定是否会引发错误),则它将中断
编辑
在通用后端代码中,如果尝试插入时区不是UTC的时间,则会引发异常
编辑2
我添加了一个更新的get_db_prep_值
,以将提供的带有时区的时间
转换为字符串,但它仅在提供的时区输出utc偏移量时起作用(如果没有日期,可能不明确)
带时区的时间似乎有点误导。。。据我所知,它实际上存储的是UTC偏移量的时间,而不是时区。因此,获取返回的值、添加日历日期以及获取夏令时的正确时间是很困难的。您的开场白(以及Django的行为)与Python处理时间对象的方式不一致。Python
time
对象可能有一个tzinfo
字段,允许时区感知的time
对象没有关联的日期,这在某些情况下很有用,例如当日期存储在别处时。我刚刚在Django的日
模型中遇到了开放时间
和关闭时间
时间字段的问题。这些时间最好是时区感知的,但不能,因为Django不支持。这很旧,但仍然有用,所以我想指出,我认为需要将clean
方法的返回值包装在from\u current\u timezone
中。