Skip to main content

django-jalali-suite

A Django utility package for Persian/Jalali calendar conversion, formatting, and model/form integrations.

django-jalali-suite helps you work with Jalali dates inside Django applications without needing to reimplement conversion logic or manually manage Persian date formatting. It gives you a simple API for conversion, formatting, and basic field/widget support.

Features

  • Jalali <-> Gregorian conversion
  • Jalali date formatting helpers like format_jalali()
  • Data-class based Jalali date values
  • Django form field support
  • Django model field support
  • Django admin compatibility for Jalali date entry and display
  • Reusable admin mixin with a Jalali datepicker
  • Custom widget and static CSS/JavaScript assets for Jalali date inputs
  • Farsi and Arabic-Indic digit input support
  • Persian datepicker labels and Farsi digit rendering
  • Persian-friendly Vazirmatn font fallback
  • Clean integration with Python and Django projects

Installation

Install from PyPI:

pip install django-jalali-suite

Or install from the source tree:

git clone https://github.com/omidshojaee/django-jalali-suite.git
cd django-jalali-suite
python -m pip install -e .

For Django REST Framework support, install the optional dependency:

python -m pip install django-jalali-suite[drf]

Add the package to INSTALLED_APPS:

INSTALLED_APPS = [
    # ... your Django apps
    "jalali_suite",
]

This enables the package's template tags, widget templates, and static assets.

Quick start

from datetime import date
from jalali_suite import JalaliDate, format_jalali, to_gregorian, to_jalali

# Gregorian to Jalali
jalali = to_jalali(date(2024, 3, 20))
print(jalali)  # JalaliDate(year=1403, month=1, day=1)
print(jalali.isoformat)  # 1403-01-01

# Jalali to Gregorian
print(to_gregorian(1403, 1, 1))  # 2024-03-20

# Formatting
print(format_jalali(date(2024, 3, 20), "%Y/%m/%d"))  # 1403/01/01

Django usage

Forms

from django import forms
from jalali_suite.forms import JalaliDateField

class ExampleForm(forms.Form):
    birthday = JalaliDateField()

This converts values from Gregorian ISO strings into Jalali date objects when cleaning form data. Render {{ form.media }} in the page <head> to load the datepicker assets and bundled Vazirmatn font.

Models

from django.db import models
from jalali_suite.models import JalaliDateField, JalaliDateTimeField

class Person(models.Model):
    birthday = JalaliDateField()
    created_at = JalaliDateTimeField()

These fields store standard Gregorian date and datetime values in the database while exposing Jalali values in Python. JalaliDateTimeField uses a split Admin widget: the date portion receives the Jalali datepicker and the time portion remains a normal time input.

Django Admin

The admin integration is provided by JalaliDateAdminMixin. It adds the Jalali date widget to JalaliDateField and the split Jalali datetime widget to JalaliDateTimeField, and loads the datepicker CSS and JavaScript assets.

Use the mixin before Django's ModelAdmin:

from django.contrib import admin
from jalali_suite.admin import JalaliDateAdminMixin
from .models import Person

@admin.register(Person)
class PersonAdmin(JalaliDateAdminMixin, admin.ModelAdmin):
    list_display = ["id", "birthday"]

Or use the convenience class:

from jalali_suite.admin import JalaliDateModelAdmin

@admin.register(Person)
class PersonAdmin(JalaliDateModelAdmin):
    list_display = ["id", "birthday"]

The datepicker opens when a Jalali date field receives focus, supports month navigation, renders Persian month names and Farsi digits, and writes a Jalali value such as ۱۴۰۳-۰۱-۰۱ back into the form field. The backend accepts Persian, Arabic-Indic, and Latin digits. No third-party JavaScript dependency is required.

The package bundles Vazirmatn Regular under its SIL OFL license. Admin media always loads the bundled font, so the widget works offline and does not require external font requests.

This is especially useful for:

  • admin forms for Persian users
  • date-based filtering in admin views
  • record entry screens where Jalali dates are expected by business users
  • making the admin experience feel native to Persian calendar workflows

Why django-jalali-suite

The package brings the full Jalali date workflow into one Django-native API:

  • conversion helpers and immutable Jalali values
  • Jalali-aware forms and model fields
  • Gregorian database storage with Jalali values in Python
  • admin widgets and a bundled Persian datepicker
  • Farsi and Arabic-Indic digit support
  • no additional JavaScript framework or calendar package required

The widget and datepicker layers are implemented and maintained inside this package. This keeps installation, configuration, and versioning in one place while allowing applications to use Jalali dates consistently across Python code, forms, models, and Django admin.

API reference

JalaliDate

A simple immutable value object representing a Jalali date.

from jalali_suite import JalaliDate

value = JalaliDate(1403, 1, 1)
print(value.isoformat)
print(value.to_gregorian())

to_jalali(value)

Converts a Gregorian date, datetime, string, or Unix timestamp to a Jalali date object.

to_gregorian(year, month, day)

Converts Jalali year/month/day to a Gregorian date value.

format_jalali(value, fmt="%Y/%m/%d")

Formats a date-like input in Jalali format using a strftime-style token set. Digits are Persian when the active Django language is Farsi (get_language() starts with "fa") and Latin otherwise; pass digits="farsi" or digits="latin" to override this for a single call.

Configuration

Override project behavior with JALALI_SUITE:

JALALI_SUITE = {
    "DATE_FORMAT": "%Y/%m/%d",
    "DATETIME_FORMAT": "%Y/%m/%d %H:%M:%S",
}

Admin list_display for Jalali fields, and the datepicker widget's digits, follow the active site language automatically — no separate setting needed.

Load template support with {% load jalali_suite %} and use the jalali, jalali_digits, and jalali_now filters/tags.

Django REST Framework

Use JalaliModelSerializer to automatically represent JalaliDateField and JalaliDateTimeField values as Jalali ISO strings and accept Latin, Persian, or Arabic-Indic digits:

from jalali_suite.serializers import JalaliModelSerializer

class PersonSerializer(JalaliModelSerializer):
    class Meta:
        model = Person
        fields = ("birthday", "created_at")

The lower-level JalaliDateSerializerField and JalaliDateTimeSerializerField are also available for custom serializers. Datetime inputs must include a time, for example 1403-01-01T12:30:00; date-only values belong in JalaliDateField.

Development

git clone https://github.com/omidshojaee/django-jalali-suite.git
cd django-jalali-suite
python -m pip install -e .[dev]
pytest

License

MIT © Omid Shojaee

Author

Release files for django-jalali-suite 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-jalali-suite 3.0.0
File Size Uploaded
django_jalali_suite-3.0.0.tar.gz 73.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-jalali-suite 3.0.0
File Interpreter ABI Platform
django_jalali_suite-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 145.2 kB

Release files / django_jalali_suite-3.0.0.tar.gz

Download URL django_jalali_suite-3.0.0.tar.gz
Size 73.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c62bbe85b98e5ad568205d9832f822683015e6cfc9eabba1553777b02304e4ad
BLAKE2b-256 checksum
How to use checksums
a77db7d896d6f03db6752dda7e58e3de5d4f481ba8109cf5f9fa502fc5cb8e18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / django_jalali_suite-3.0.0-py3-none-any.whl

Download URL django_jalali_suite-3.0.0-py3-none-any.whl
Size 71.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02fafb2dcd23b44c5e1ef6dec792aff8608120da02c3ef0c576b8b3c755b8c43
BLAKE2b-256 checksum
How to use checksums
910b7d1c8b6d560169786c2d3a1b3006f0e3840a25ac048f0f8e89e5c96712f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.0.10

2 release files

2.0.9

2 release files

2.0.8

2 release files

2.0.7

2 release files

2.0.6

2 release files

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page