Skip to main content

django-dynamic-translations

Model-specific translations for Django without a shared generic translation table. The package generates a <Model>Translation model from each TranslatedField, exposes the translated values as natural model attributes, and integrates all configured languages into a single Django form or admin page.

The project is currently in alpha. Its public API is usable, but may still evolve before version 1.0.

Installation

Install the package:

pip install django-dynamic-translations

Then add it to INSTALLED_APPS and configure only the languages supported by the application:

INSTALLED_APPS = [
    # ...
    "django_dynamic_translations",
]

LANGUAGE_CODE = "en-us"
LANGUAGES = [
    ("en-us", "English (United States)"),
    ("it", "Italiano"),
]

Only put application-supported languages in LANGUAGES: each language becomes a section in the generated form.

Model

from django.db import models
from django_dynamic_translations.models import TranslatableModel, TranslatedField


class Trip(TranslatableModel):
    name = TranslatedField[str](models.CharField(max_length=255))
    slug = TranslatedField[str](models.SlugField(max_length=255))
    description = TranslatedField[str](models.TextField())

Run makemigrations normally. Django creates both Trip and TripTranslation. The default-language translation is required. Other languages fall back to it when read through trip.name, trip.slug, or the other aliases.

Use prefetch_translations() for lists and paginated querysets:

trips = Trip.objects.order_by("pk").prefetch_translations()

Forms and admin

from django.contrib import admin
from django_dynamic_translations.admin import TranslatableAdmin
from django_dynamic_translations.forms import TranslatableModelForm

from .models import Trip


class TripForm(TranslatableModelForm):
    class Meta:
        model = Trip
        fields = ()


@admin.register(Trip)
class TripAdmin(TranslatableAdmin):
    form = TripForm
    list_display = ("name", "slug")
    search_fields = ("translations__name", "translations__slug")

For generated forms without a custom subclass, use translatable_modelform_factory(Trip).

The form displays all translated fields for all configured languages. The default language is mandatory. An optional language is saved only when it is complete; clearing every field removes that translation.

Development

The project uses uv:

uv sync
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest

Releases

GitHub releases publish the matching wheel and source distribution to PyPI through Trusted Publishing. The Git tag must match the package version, for example v0.1.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_dynamic_translations-0.1.0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_dynamic_translations-0.1.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file django_dynamic_translations-0.1.0.tar.gz.

File metadata

File hashes

Hashes for django_dynamic_translations-0.1.0.tar.gz
Algorithm Hash digest
SHA256 35be5757cb3ecfbe011cfcf89b8b9122c87c05dd66c0409f6226a51923369d16
MD5 55271929cb6d1feeda9d4438cd4618c5
BLAKE2b-256 d6d02e15f55d1645f83538a4d084efe018c7b8ceda252a411a597257fa5f4352

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_dynamic_translations-0.1.0.tar.gz:

Publisher: publish.yml on AndreaBellomia/django-dynamic-translations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_dynamic_translations-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_dynamic_translations-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 13d4cc859ac699f86540a961bfd67b5ba76f3dac0b50588449d17ff30c732e96
MD5 c83509f925597defe6e6aeefa25a6c49
BLAKE2b-256 f96b3196a090aaa3b4c01e046f820c3f47729c64f7db59bb69912bb1865a4324

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_dynamic_translations-0.1.0-py3-none-any.whl:

Publisher: publish.yml on AndreaBellomia/django-dynamic-translations

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page