跳转到主要内容

一个提供DB、表单和REST框架字段的Django应用,用于处理zoneinfo和pytz时区对象。

项目描述

django-timezone-field

CI codecov pypi downloads pypi python support pypi django support

一个提供DB、表单和REST框架字段的Django应用,用于处理zoneinfopytz时区对象。

pytzzoneinfo的过渡

像Django一样,此应用同时支持pytzzoneinfo对象,当社区从pytz过渡到zoneinfo时。所有公开的字段和返回时区对象的函数都接受一个可选的布尔参数use_pytz

如果没有明确指定,use_pytz的默认值与Django的行为相匹配

请注意,此应用未将 pytz 声明为依赖项,因此如果您使用此应用且 use_pytz=True,您需要自行确保环境中包含 pytz

pytzzoneinfo 识别时区之间的差异

pytzzoneinfo 搜索时区数据的方式不同。

  • pytz 将其自身的 IANA 时区数据库 打包并搜索其中
  • zoneinfo 首先在本地系统的时区数据库中搜索匹配项。如果未找到匹配项,然后它会在已安装的情况下搜索 tzdata 包内。该 tzdata 包包含 IANA 时区数据库的副本。

如果本地系统的时区数据库未涵盖整个 IANA 时区数据库且未安装 tzdata 包,则在从 pytz 切换到 zoneinfo 时可能会遇到错误,例如 ZoneInfoNotFoundError: 'No time zone found with key Pacific/Kanton',对于看似有效的时区,这是一个简单的修复,可以通过 poetry add tzdatapip install tzdatatzdata 添加到您的项目中。

假设您已安装所需的 tzdata 包,则在从 pytz 切换到 zoneinfo 时不需要进行任何 数据迁移

示例

数据库字段

import zoneinfo
import pytz
from django.db import models
from timezone_field import TimeZoneField

class MyModel(models.Model):
    tz1 = TimeZoneField(default="Asia/Dubai")               # defaults supported, in ModelForm renders like "Asia/Dubai"
    tz2 = TimeZoneField(choices_display="WITH_GMT_OFFSET")  # in ModelForm renders like "GMT+04:00 Asia/Dubai"
    tz3 = TimeZoneField(use_pytz=True)                      # returns pytz timezone objects
    tz4 = TimeZoneField(use_pytz=False)                     # returns zoneinfo objects

my_model = MyModel(
    tz2="America/Vancouver",                     # assignment of a string
    tz3=pytz.timezone("America/Vancouver"),      # assignment of a pytz timezone
    tz4=zoneinfo.ZoneInfo("America/Vancouver"),  # assignment of a zoneinfo
)
my_model.full_clean() # validates against pytz.common_timezones by default
my_model.save()       # values stored in DB as strings
my_model.tz3          # value returned as pytz timezone: <DstTzInfo 'America/Vancouver' LMT-1 day, 15:48:00 STD>
my_model.tz4          # value returned as zoneinfo: zoneinfo.ZoneInfo(key='America/Vancouver')

my_model.tz1 = "UTC"  # assignment of a string, immediately converted to timezone object
my_model.tz1          # zoneinfo.ZoneInfo(key='UTC') or pytz.utc, depending on use_pytz default
my_model.tz2 = "Invalid/Not_A_Zone"  # immediately raises ValidationError

表单字段

from django import forms
from timezone_field import TimeZoneFormField

class MyForm(forms.Form):
    tz1 = TimeZoneFormField()                                   # renders like "Asia/Dubai"
    tz2 = TimeZoneFormField(choices_display="WITH_GMT_OFFSET")  # renders like "GMT+04:00 Asia/Dubai"
    tz3 = TimeZoneFormField(use_pytz=True)                      # returns pytz timezone objects
    tz4 = TimeZoneFormField(use_pytz=False)                     # returns zoneinfo objects

my_form = MyForm({"tz3": "Europe/Berlin", "tz4": "Europe/Berlin"})
my_form.full_clean()         # validates against pytz.common_timezones by default
my_form.cleaned_data["tz3"]  # value returned as pytz timezone: <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>
my_form.cleaned_data["tz4"]  # value returned as zoneinfo: zoneinfo.ZoneInfo(key='Europe/Berlin')

REST 框架序列化字段

from rest_framework import serializers
from timezone_field.rest_framework import TimeZoneSerializerField

class MySerializer(serializers.Serializer):
    tz1 = TimeZoneSerializerField(use_pytz=True)
    tz2 = TimeZoneSerializerField(use_pytz=False)

my_serializer = MySerializer(data={
    "tz1": "America/Argentina/Buenos_Aires",
    "tz2": "America/Argentina/Buenos_Aires",
})
my_serializer.is_valid()
my_serializer.validated_data["tz1"]  # <DstTzInfo 'America/Argentina/Buenos_Aires' LMT-1 day, 20:06:00 STD>
my_serializer.validated_data["tz2"]  # zoneinfo.ZoneInfo(key='America/Argentina/Buenos_Aires')

安装

版本发布在 pypi 上,并可以使用各种 Python 打包工具进行安装。

# with poetry
poetry add django-timezone-field

# with pip
pip install django-timezone-field

运行测试

从存储库根目录,使用 poetry

poetry install
poetry run pytest

变更日志

7.0 (2024-07-07)

  • 改进了 choices 的默认排序(#116),(#123
  • 在创建/分配时立即将字符串值转换为时区对象。访问 TimeZoneField 将始终返回一个时区或 None(永远不会是字符串)。(可能会破坏:未知时区名称现在在分配时引发 ValidationError。之前,转换被延迟到模型的 full_cleansave。)(#57
  • 添加对 django 5.1 的支持
  • 停止支持 django 3.2、4.0、4.1
  • TimeZoneSerializerField 的基类从 DJRF 的 Field 更改为 CharField#137

6.1.0 (2023-11-25)

  • 添加对 django 5.0 的支持
  • 添加对 python 3.12 的支持
  • 修复某些 BSD 系统上 Factory 时区的问题(#114

6.0.1 (2023-09-07)

  • 在运行 django 3.X 时使用正确的默认后端(#109

6.0 (2023-08-20)

  • 破坏性变更:已从依赖项中删除 pytz。如果您使用此包且 use_pytz=True,则需要自行安装 pytz
  • 停止支持 django 2.2
  • 停止支持 python 3.7

5.1 (2023-06-18)

  • 将 django 作为此包的依赖项添加,并带有正确的版本约束(#90
  • 添加对 django 4.1、4.2 的支持
  • 添加对 python 3.11 的支持

5.0 (2022-02-08)

  • 添加对 zoneinfo 对象的支持(#79
  • 添加对 django 4.0 的支持
  • 删除 timezone_field.utils.add_gmt_offset_to_choicesdisplay_GMT_offset 参数(使用 choices_display 代替)
  • 停止支持 django 3.0、3.1
  • 停止支持 python 3.5、3.6

4.2.3 (2022-01-13)

  • 修复 sdist 安装问题(#78
  • 正式支持 python 3.10

4.2.1 (2021-07-07)

  • 恢复 TimeZoneField.default_choices#76

4.2 (2021-07-07)

  • 官方支持django 3.2,python 3.9
  • 修复字段解构错误(#74
  • 维护:使用poetry,github actions,pytest

4.1.2 (2021-03-17)

  • 避免DST转换期间的NonExistentTimeError#70

4.1.1 (2020-11-28)

  • 不要从包根目录导入rest_framework#67

4.1 (2020-11-28)

  • 添加Django REST Framework序列化器字段
  • 添加新的choices_display关键字参数,支持值WITH_GMT_OFFSETSTANDARD
  • 弃用display_GMT_offset关键字参数

4.0 (2019-12-03)

  • 添加对django 3.0、python 3.8的支持
  • 放弃对django 1.11、2.0、2.1、python 2.7、3.4的支持

3.1 (2019-10-02)

  • 官方支持django 2.2(已工作)
  • 添加选项以在表单字段中显示时区偏移量(#46

3.0 (2018-09-15)

  • 支持django 1.11、2.0、2.1
  • 添加对python 3.7的支持
  • 将默认人类可读时区名称更改为排除下划线(#32 & #37

2.1 (2018-03-01)

  • 添加对django 1.10、1.11的支持
  • 添加对python 3.6的支持
  • 添加wheel支持
  • 支持数据库字段中的bytes类型(#38 & #39

2.0 (2016-01-31)

  • 放弃对django 1.7的支持,添加对django 1.9的支持
  • 放弃对python 3.2、3.3的支持,添加对python 3.5的支持
  • 从源分布中删除测试

1.3 (2015-10-12)

  • 放弃对django 1.6的支持,添加对django 1.8的支持
  • 各种错误修复

1.2 (2015-02-05)

  • 对于表单字段,将默认接受时区列表从pytz.all_timezones更改为pytz.common_timezones,以匹配数据库字段的行为。

1.1 (2014-10-05)

  • Django 1.7兼容性
  • 添加了对将choices关键字参数格式化为[[<str>, <str>], ...]的支持,除了之前的格式[[<pytz.timezone>, <str>], ...]
  • 将默认接受时区列表从pytz.all_timezones更改为pytz.common_timezones。如果您数据库中有时区位于pytz.all_timezones但不在pytz.common_timezones中,这是一个不兼容的更改。可以通过在模型定义中指定choices=[(tz, tz) for tz in pytz.all_timezones]来恢复旧的行为。

1.0 (2013-08-04)

  • 作为timezone_field的初始发布。

致谢

最初改编自Brian Rosner的django-timezones

归功于贡献者的工作。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

django_timezone_field-7.0.tar.gz (13.7 kB 查看散列)

上传于

构建的发行版

django_timezone_field-7.0-py3-none-any.whl (13.2 kB 查看哈希值)

上传于 Python 3

由以下支持