This commit is contained in:
Iliyan Angelov
2025-09-19 11:58:53 +03:00
parent 306b20e24a
commit 6b247e5b9f
11423 changed files with 1500615 additions and 778 deletions

View File

@@ -0,0 +1,23 @@
Copyright (c) 2014, Mike Fogel <mike@fogel.ca>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,311 @@
Metadata-Version: 2.1
Name: django-timezone-field
Version: 7.1
Summary: A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects.
Home-page: https://github.com/mfogel/django-timezone-field/
License: BSD-2-Clause
Author: Mike Fogel
Author-email: mike@fogel.ca
Requires-Python: >=3.8,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Requires-Dist: Django (>=3.2,<6.0)
Requires-Dist: backports.zoneinfo (>=0.2.1,<0.3.0) ; python_version < "3.9"
Project-URL: Repository, https://github.com/mfogel/django-timezone-field/
Description-Content-Type: text/markdown
# django-timezone-field
[![CI](https://github.com/mfogel/django-timezone-field/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mfogel/django-timezone-field/actions)
[![codecov](https://codecov.io/gh/mfogel/django-timezone-field/branch/main/graph/badge.svg?token=Rwekzmim3l)](https://codecov.io/gh/mfogel/django-timezone-field)
[![pypi downloads](https://img.shields.io/pypi/dm/django-timezone-field.svg)](https://pypi.python.org/pypi/django-timezone-field/)
[![pypi python support](https://img.shields.io/pypi/pyversions/django-timezone-field.svg)](https://pypi.python.org/pypi/django-timezone-field/)
[![pypi django support](https://img.shields.io/pypi/djversions/django-timezone-field.svg)](https://pypi.python.org/pypi/django-timezone-field/)
A Django app providing DB, form, and REST framework fields for
[`zoneinfo`](https://docs.python.org/3/library/zoneinfo.html) and [`pytz`](http://pypi.python.org/pypi/pytz/) timezone
objects.
## The transition from `pytz` to `zoneinfo`
Like Django, this app supports both `pytz` and `zoneinfo` objects while the community transitions away from `pytz` to
`zoneinfo`. All exposed fields and functions that return a timezone object accept an optional boolean kwarg `use_pytz`.
If not explicitly specified, the default value used for `use_pytz` matches Django's behavior:
- Django <= 3.X: `use_pytz` defaults to `True`
- Django == 4.X: `use_pytz` defaults to the value of
[`django.conf.settings.USE_DEPRECATED_PYTZ`](https://docs.djangoproject.com/en/4.0/ref/settings/#use-deprecated-pytz),
which itself defaults to `False`
- Django >= 5.X:
[drops support for `pytz` altogether](https://docs.djangoproject.com/en/5.0/releases/5.0/#features-removed-in-5-0),
and this app has done the same.
Note that this app does _not_ declare `pytz` to be a dependency, so if you're using this app with `use_pytz=True`, you'll need
to ensure `pytz` is included in the environment yourself.
### Differences in recognized timezones between `pytz` and `zoneinfo`
`pytz` and `zoneinfo` search for timezone data differently.
- `pytz` bundles and searches within its own copy of the [IANA timezone DB](https://www.iana.org/time-zones)
- `zoneinfo` first searches the local system's timezone DB for a match. If no match is found, it then searches within
the [`tzdata`](https://pypi.org/project/tzdata/) package _if it is installed_. The `tzdata` package contains a copy of
the IANA timezone DB.
If the local system's timezone DB doesn't cover the entire IANA timezone DB and the `tzdata` package is not installed,
you may run across errors like `ZoneInfoNotFoundError: 'No time zone found with key Pacific/Kanton'` for seemingly valid
timezones when transitioning from `pytz` to `zoneinfo`. The easy fix is to add `tzdata` to your project with
`poetry add tzdata` or `pip install tzdata`.
Assuming you have the `tzdata` package installed if needed, no
[data migration](https://docs.djangoproject.com/en/4.0/topics/migrations/#data-migrations) should be necessary when
switching from `pytz` to `zoneinfo`.
## Examples
### Database Field
```python
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
```
### Form Field
```python
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 Framework Serializer Field
```python
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')
```
## Installation
Releases are hosted on [`pypi`](https://pypi.org/project/django-timezone-field/) and can be installed using various
python packaging tools.
```bash
# with poetry
poetry add django-timezone-field
# with pip
pip install django-timezone-field
```
## Running the tests
From the repository root, with [`poetry`](https://python-poetry.org/):
```bash
poetry install
poetry run pytest
```
## Changelog
#### 7.1 (2025-01-11)
- Add support for python 3.13
#### 7.0 (2024-07-07)
- Better default sorting of `choices` ([#116](https://github.com/mfogel/django-timezone-field/issues/116)), ([#123](https://github.com/mfogel/django-timezone-field/issues/123))
- Convert string value to timezone object immediately on creation/assignment.
Accessing a TimeZoneField will _always_ return a timezone or None (never a string).
(Potentially BREAKING: Unknown timezone names now raise `ValidationError` at time of assignment.
Previously, conversion was delayed until model `full_clean` or `save`.)
([#57](https://github.com/mfogel/django-timezone-field/issues/57))
- Add support for django 5.1
- Drop support for django 3.2, 4.0, 4.1
- Change base class of `TimeZoneSerializerField` from DJRF's `Field` to `CharField` ([#137](https://github.com/mfogel/django-timezone-field/issues/137))
#### 6.1.0 (2023-11-25)
- Add support for django 5.0
- Add support for python 3.12
- Fix issue with `Factory` timezone on some BSD systems ([#114](https://github.com/mfogel/django-timezone-field/issues/114))
#### 6.0.1 (2023-09-07)
- Use correct default backend when running with django 3.X ([#109](https://github.com/mfogel/django-timezone-field/issues/109))
#### 6.0 (2023-08-20)
- BREAKING: `pytz` removed from dependencies. If you use this package with `use_pytz=True`, you'll need to install
`pytz` yourself.
- Drop support for django 2.2
- Drop support for python 3.7
#### 5.1 (2023-06-18)
- Add django as a dependency of this package, with correct version constraints
([#90](https://github.com/mfogel/django-timezone-field/issues/90))
- Add support for django 4.1, 4.2
- Add support for python 3.11
#### 5.0 (2022-02-08)
- Add support for `zoneinfo` objects ([#79](https://github.com/mfogel/django-timezone-field/issues/79))
- Add support for django 4.0
- Remove `timezone_field.utils.add_gmt_offset_to_choices`, `display_GMT_offset` kwarg (use `choices_display` instead)
- Drop support for django 3.0, 3.1
- Drop support for python 3.5, 3.6
#### 4.2.3 (2022-01-13)
- Fix sdist installs ([#78](https://github.com/mfogel/django-timezone-field/issues/78))
- Officially support python 3.10
#### 4.2.1 (2021-07-07)
- Reinstate `TimeZoneField.default_choices` ([#76](https://github.com/mfogel/django-timezone-field/issues/76))
#### 4.2 (2021-07-07)
- Officially support django 3.2, python 3.9
- Fix bug with field deconstruction ([#74](https://github.com/mfogel/django-timezone-field/issues/74))
- Housekeeping: use poetry, github actions, pytest
#### 4.1.2 (2021-03-17)
- Avoid `NonExistentTimeError` during DST transition ([#70](https://github.com/mfogel/django-timezone-field/issues/70))
#### 4.1.1 (2020-11-28)
- Don't import `rest_framework` from package root ([#67](https://github.com/mfogel/django-timezone-field/issues/67))
#### 4.1 (2020-11-28)
- Add Django REST Framework serializer field
- Add new `choices_display` kwarg with supported values `WITH_GMT_OFFSET` and `STANDARD`
- Deprecate `display_GMT_offset` kwarg
#### 4.0 (2019-12-03)
- Add support for django 3.0, python 3.8
- Drop support for django 1.11, 2.0, 2.1, python 2.7, 3.4
#### 3.1 (2019-10-02)
- Officially support django 2.2 (already worked)
- Add option to display TZ offsets in form field ([#46](https://github.com/mfogel/django-timezone-field/issues/46))
#### 3.0 (2018-09-15)
- Support django 1.11, 2.0, 2.1
- Add support for python 3.7
- Change default human-readable timezone names to exclude underscores
([#32](https://github.com/mfogel/django-timezone-field/issues/32) &
[#37](https://github.com/mfogel/django-timezone-field/issues/37))
#### 2.1 (2018-03-01)
- Add support for django 1.10, 1.11
- Add support for python 3.6
- Add wheel support
- Support bytes in DB fields ([#38](https://github.com/mfogel/django-timezone-field/issues/38) &
[#39](https://github.com/mfogel/django-timezone-field/issues/39))
#### 2.0 (2016-01-31)
- Drop support for django 1.7, add support for django 1.9
- Drop support for python 3.2, 3.3, add support for python 3.5
- Remove tests from source distribution
#### 1.3 (2015-10-12)
- Drop support for django 1.6, add support for django 1.8
- Various [bug fixes](https://github.com/mfogel/django-timezone-field/issues?q=milestone%3A1.3)
#### 1.2 (2015-02-05)
- For form field, changed default list of accepted timezones from `pytz.all_timezones` to `pytz.common_timezones`, to
match DB field behavior.
#### 1.1 (2014-10-05)
- Django 1.7 compatibility
- Added support for formatting `choices` kwarg as `[[<str>, <str>], ...]`, in addition to previous format of
`[[<pytz.timezone>, <str>], ...]`.
- Changed default list of accepted timezones from `pytz.all_timezones` to `pytz.common_timezones`. If you have timezones
in your DB that are in `pytz.all_timezones` but not in `pytz.common_timezones`, this is a backward-incompatible
change. Old behavior can be restored by specifying `choices=[(tz, tz) for tz in pytz.all_timezones]` in your model
definition.
#### 1.0 (2013-08-04)
- Initial release as `timezone_field`.
## Credits
Originally adapted from [Brian Rosner's django-timezones](https://github.com/brosner/django-timezones).
Made possible thanks to the work of the
[contributors](https://github.com/mfogel/django-timezone-field/graphs/contributors).

View File

@@ -0,0 +1,27 @@
django_timezone_field-7.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
django_timezone_field-7.1.dist-info/LICENSE.txt,sha256=TvTn3IwTDSWU8uXVQR-_GHTRUAI7ZC0b5WexaMOQ7us,1333
django_timezone_field-7.1.dist-info/METADATA,sha256=h2fISuEAuKREhMvQTSxqn5gXFh-lbXi6SoY7z-ne56E,13083
django_timezone_field-7.1.dist-info/RECORD,,
django_timezone_field-7.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
timezone_field/__init__.py,sha256=i_B9vFCAqoBaP9FLs_Bl09psqpkCRBuL0kNEvphLS9I,169
timezone_field/__pycache__/__init__.cpython-312.pyc,,
timezone_field/__pycache__/choices.cpython-312.pyc,,
timezone_field/__pycache__/fields.cpython-312.pyc,,
timezone_field/__pycache__/forms.cpython-312.pyc,,
timezone_field/__pycache__/models.cpython-312.pyc,,
timezone_field/__pycache__/rest_framework.cpython-312.pyc,,
timezone_field/__pycache__/utils.cpython-312.pyc,,
timezone_field/backends/__init__.py,sha256=llZvKMLq7-THyb93txT1k08gDYiXURWB38PKMuV6kzE,656
timezone_field/backends/__pycache__/__init__.cpython-312.pyc,,
timezone_field/backends/__pycache__/base.cpython-312.pyc,,
timezone_field/backends/__pycache__/pytz.cpython-312.pyc,,
timezone_field/backends/__pycache__/zoneinfo.cpython-312.pyc,,
timezone_field/backends/base.py,sha256=WN2YKcQR6yraLjalJ7G7r71ZmMoZLgUXbafFqX3Sbmk,313
timezone_field/backends/pytz.py,sha256=92zV5s5tzpDigICuq6GeAaIa1SM4d3MD4s46MZmpyME,502
timezone_field/backends/zoneinfo.py,sha256=DfQm9neXOPW7dcOjaComT4KLy9iCSIF9NIwntUTueTw,887
timezone_field/choices.py,sha256=DvU4m3Rs6tFkbHW4rzKYpiNb6qjd7VRQkXd0jWrDgT4,2249
timezone_field/fields.py,sha256=mmqrmx58wkpowXeWIYEMKghWYjFIISWoZyCZdm4qX9U,6740
timezone_field/forms.py,sha256=Vdsqv931u3s-caiT9DbJ0dUe_-Wqefw49yxODBNsvR4,1527
timezone_field/models.py,sha256=6IvMzAmr0-Z6oqTkZcgXgrkJrQXVMjBih2AZvLdDgOE,27
timezone_field/rest_framework.py,sha256=O_OprYAGahSamzncDNwjtnKfK4ArhQlv8f4xmYbFn2g,836
timezone_field/utils.py,sha256=oempK8eECi9bu9nrxmMy2QXcL3cEgAkVCfdKDRQxvoU,725

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: poetry-core 1.9.1
Root-Is-Purelib: true
Tag: py3-none-any