Django Timezone Field
django-timezone-field is an actively maintained Django app that provides database, form, and Django REST Framework fields for handling `zoneinfo` and `pytz` timezone objects. It is currently at version 7.2.1 (released December 2025) and regularly updates to support the latest Django and Python versions. Its primary function is to simplify the storage and manipulation of timezone data within Django applications, abstracting away the complexities of `pytz` and the newer `zoneinfo` module.
Common errors
-
ModuleNotFoundError: No module named 'timezone_field'
cause The `django-timezone-field` package has not been installed in your Python environment or is not accessible on the Python path.fixRun `pip install django-timezone-field` to install the package. -
ZoneInfoNotFoundError: 'No time zone found with key Pacific/Kanton'
cause When using `zoneinfo` (the default for Django 4.x+ and Python 3.9+), the specified timezone key cannot be found, typically because the `tzdata` package is not installed or the local system's timezone database is incomplete.fixInstall the `tzdata` package: `pip install tzdata`. -
ValidationError: {'timezone': ["Value <DstTzInfo 'Africa/Asmera' LMT+2:27:00 STD> is not a valid choice."]}cause The provided timezone value is not recognized as a valid choice for the `TimeZoneField`, often because the default choices were changed from `pytz.all_timezones` to `pytz.common_timezones` in older versions of the library, or the input string is not a valid IANA timezone key.fixEnsure you are providing a valid IANA timezone string (e.g., 'America/New_York'). If you need to support a wider range of timezones than `pytz.common_timezones`, explicitly set the `choices` argument in your model field definition: `timezone = TimeZoneField(choices=[(tz, tz) for tz in pytz.all_timezones])` (requires `pytz` installed). -
AttributeError: type object 'TimeZoneField' has no attribute 'CHOICES'
cause This error often arises from version incompatibility between `django-timezone-field` and other libraries (like `django-celery-beat`) that expect a `CHOICES` attribute on `TimeZoneField`, which might have been removed or refactored in newer versions of `django-timezone-field`.fixPin your `django-timezone-field` version to one compatible with your other dependencies (e.g., `django-timezone-field==4.0` for older `django-celery-beat`), or update all related packages to their latest compatible versions.
Warnings
- breaking Breaking change in `django-timezone-field` 6.0: `pytz` was removed as a direct dependency. If your project relies on `use_pytz=True` (which is often the default for Django < 5.x), you must explicitly `pip install pytz` in your project's environment.
- breaking Breaking change in `django-timezone-field` 7.0: Assigning a string to a `TimeZoneField` now immediately converts it to a timezone object and raises a `ValidationError` if the string is not a recognized timezone. Previously, this conversion and validation might have been delayed until `full_clean` or `save`.
- gotcha When using `zoneinfo` (default for Python 3.9+ and modern Django), `ZoneInfoNotFoundError` can occur if the local system's timezone database does not contain the requested timezone.
- gotcha Django 5.x and later have fully deprecated `pytz` in favor of `zoneinfo`. While `django-timezone-field` supports both, be aware of Django's native behavior.
- gotcha Prior to `django-timezone-field` version 7.0, the default choices for the form field transitioned from `pytz.all_timezones` to `pytz.common_timezones` (in versions 1.1/1.2). If your application relies on timezones outside of `common_timezones`, you might encounter validation errors.
- gotcha Always use timezone-aware `datetime` objects (e.g., `django.utils.timezone.now()`) when `USE_TZ = True` in Django settings, rather than naive `datetime.datetime.now()`. Mixing aware and naive datetimes leads to `TypeError: can't compare offset-naive and offset-aware datetimes`.
- gotcha Importing `django-timezone-field` components (e.g., `TimeZoneField`) in an environment where Django settings are not configured will raise `django.core.exceptions.ImproperlyConfigured`. This is because the library accesses `Django.conf.settings` during its initialization.
- gotcha Importing `django-timezone-field` components requires Django settings to be configured. If Django settings are not set up (e.g., in a standalone script or test environment without `DJANGO_SETTINGS_MODULE` environment variable or an explicit `settings.configure()` call), a `django.core.exceptions.ImproperlyConfigured` error will occur when the library attempts to access `django.conf.settings` during import.
Install
-
pip install django-timezone-field
Imports
- TimeZoneField
from timezone_field.fields import TimeZoneField
- TimeZoneSerializerField
from timezone_field.rest_framework import TimeZoneSerializerField
Quickstart
from django.db import models
from timezone_field import TimeZoneField
# For ZoneInfo (Python 3.9+ / modern Django) or pytz (older Django)
# You might need 'tzdata' installed for ZoneInfo if your system's timezone DB is incomplete.
class Event(models.Model):
name = models.CharField(max_length=255)
# Default behavior (uses zoneinfo on Django >= 5.x, pytz on older)
timezone = TimeZoneField(default="UTC")
# Example with explicit pytz usage (requires pytz installed if on >= 6.0)
# For Django < 5.x, this field would default to use_pytz=True implicitly.
# from pytz import timezone
# explicit_pytz_tz = TimeZoneField(use_pytz=True, default=timezone('America/New_York'))
# Example with choices_display for forms
# from timezone_field.choices import WITH_GMT_OFFSET
# display_timezone = TimeZoneField(choices_display=WITH_GMT_OFFSET)
def __str__(self):
return f"{self.name} ({self.timezone})"
# Example usage:
# event = Event.objects.create(name="Meeting", timezone="America/Los_Angeles")
# print(event.timezone) # Returns a zoneinfo.ZoneInfo or pytz.timezone object