Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如何使TimeField时区意识到?_Django - Fatal编程技术网

Django 如何使TimeField时区意识到?

Django 如何使TimeField时区意识到?,django,Django,有时,您需要从用户处收集时间而不收集相关日期。例如,如果用户正在配置每天同时运行的重复事件。Django的TimeField不使用时区。然而,在这种特殊情况下(可能在任何时候你自己记录时间),时区是一个重要因素。那么,您如何存储时区感知时间呢?答案是您没有。要使时间具有时区意识,它必须有一个与之关联的日期。想想夏令时。。。我的解决方案是在模型上使用DateTimeField,并覆盖表单,如下所示: # Model class MyModel(models.Model): time_of_

有时,您需要从用户处收集时间而不收集相关日期。例如,如果用户正在配置每天同时运行的重复事件。Django的
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
中。