Django 时区字段不接受所有 pytz 时区

Posted

技术标签:

【中文标题】Django 时区字段不接受所有 pytz 时区【英文标题】:Django timezone fields don't accept all pytz timezones 【发布时间】:2018-10-20 14:17:14 【问题描述】:

Django timezone fields 建立在pytz timezones 之上,但后者的某些时区对字段无效。像

这样的模型
from django.db import models
from timezone_field import TimeZoneField

class TestModel(models.Model):
    timezone_field = TimeZoneField(default='UTC')

def save(self, *args, **kwargs):
    self.clean()
    self.full_clean()
    super().save(*args, **kwargs)

如果我运行(在 shell 中)

import pytz
from models import TestModel

model = TestModel.objects.get(id=1)

for zone in pytz.all_timezones:
    model.timezone = zone
    model.save()

我明白了

django.core.exceptions.ValidationError: 'timezone': ["Value <DstTzInfo 'Africa/Asmera' LMT+2:27:00 STD> is not a valid choice."]

所以它首先在'Africa/Asmera' 上失败(它在其他人上也失败了,例如'GMT+0')。

知道如何解决这种不一致吗?目前,用户可以在前端选择一个时区,这会导致后端错误(前端内置在 React 中,并从 moment timezone 获取时区)

【问题讨论】:

选项只有common_timezones,而不是all_timezones 啊哈..知道如何将common_timezones 转换为 javascript 吗? (除了打印它们并保存在文件中)?另外,如果您将其写为答案,我会接受 您现在如何在 JavaScript 中获取时区?该软件包支持表单字段,据我所知,它们也是common_timezones 我从时刻时区得到它们:momentjs.com/timezone 这个包有一个表单域的功能。所以你可以使用附加的表单域。 【参考方案1】:

正如 Willem 在 Django 时区字段 V1.2 中提到的,他们将字段的默认选项从 all_timezones 更改为 common_timezones。您可以通过在字段定义中显式设置 choices 属性来恢复此更改。

https://github.com/mfogel/django-timezone-field

1.2 (2015-02-05) 对于表单字段,将接受时区的默认列表从 pytz.all_timezones 更改为 pytz.common_timezones,以匹配 数据库字段行为。 1.1 (2014-10-05) Django 1.7 兼容性除了以前的格式外,还添加了对格式化选项 kwarg 的支持为 [[, ], ...] 的 [[, ], ...]。更改了接受的默认列表 从 pytz.all_timezones 到 pytz.common_timezones 的时区。如果你 您的数据库中有时区在 pytz.all_timezones 但不在 pytz.common_timezones,这是一个向后不兼容的更改。老的 可以通过为 tz in 指定 options=[(tz, tz) 来恢复行为 pytz.all_timezones] 在您的模型定义中。

class TestModel(models.Model):
    timezone_field = TimeZoneField(default='UTC', choices=[(tz, tz) for tz in pytz.all_timezones])

有一个关于这是一个向后不兼容的变化的免责声明;所以我敦促你进一步调查

【讨论】:

以上是关于Django 时区字段不接受所有 pytz 时区的主要内容,如果未能解决你的问题,请参考以下文章

Python pytz 时区转换返回的值与不同日期的时区偏移量不同

Django datetimefield 时区感知 CET

pytz:为啥在时区之间转换时需要规范化?

pytz:获取所有时区,现在是特定时间

使用 pytz 时区时 Python 日期时间不包括 DST

pytz:获取所有时区,现在在特定时间范围之间