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 时区转换返回的值与不同日期的时区偏移量不同