Skip to main content
django-klingon

django-klingon

Tests Coverage

Welcome to the documentation for django-klingon!

django-klingon is an attempt to make django model translations suck but with no integrations pain in your app!

Setup & Integration

In your settings files: add django-klingon to INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'klingon',
    ...
)

specify a default language if you want to use your fields to store the default language:

KLINGON_DEFAULT_LANGUAGE = 'en'

Extend you models to add API support: first add Translatable to your model Class definition. This will add the API functions:

from klingon.models import Translatable
...
class Book(models.Model, Translatable):
...

in the same model add an attribute to indicate which fields will be translatables:

    ...
    translatable_fields = ('title', 'description')
    ...

your model should look like this:

class Book(models.Model, Translatable):
    title = models.CharField(max_length=100)
    description = models.TextField()
    publication_date = models.DateField()

    translatable_fields = ('title', 'description')

Translating an autoslug field:

If you use django-easy-autoslug's AutoSlugField and want the slug itself translated per-language, set translatable_slug to the slug field's name and pass title_field to the field so klingon knows which field to slugify from:

from django_autoslugfield import AutoSlugField

class Book(models.Model, Translatable):
    title = models.CharField(max_length=100)
    slug = AutoSlugField(title_field='title')

    translatable_fields = ('title',)
    translatable_slug = 'slug'

title_field is optional in django-easy-autoslug (unlike the old django-autoslug, where the equivalent populate_from was mandatory). A bare AutoSlugField() with no title_field is valid and will not crash, but klingon silently skips per-language slug translation for it.

Add admin capabilities:

you can include an inline to your model admin and a custom action to create the translations. To do this in your ModelAdmin class do this:

from klingon.admin import TranslationInline, create_translations
...
class BookAdmin(admin.ModelAdmin):
    ...
    inlines = [TranslationInline]
    actions = [create_translations]
  • see full example in the klingon-example repo (sibling project to django-klingon)

Using Specific Widgets in the TranslationInline form of the admin:

You can specify the widget to be use on an inline form by passing a dictionary to TranslationInlineForm. So, you might want to extend the TranslationInline with a new form that will a "widgets" dictionary, where you can specify the widget that each filds has to use, for example:

class RichTranslationInlineForm(TranslationInlineForm):
    widgets = {
        'CharField': forms.TextInput(attrs={'class': 'klingon-char-field'}),
        'TextField': forms.Textarea(attrs={'class': 'klingon-text-field'}),
    }

class RichTranslationInline(TranslationInline):
    form = RichTranslationInlineForm

and then you just simply use the RichTranslationInline class on your AdminModels, for example:

class BookAdmin(admin.ModelAdmin):
    inlines = [RichTranslationInline]
  • see full example in the klingon-example repo (sibling project to django-klingon)

Using the API

To create the translation you can do the follwing:

Suppose that you have and object called book:

> book = Book.objects.create(
    title="The Raven",
    description="The Raven is a narrative poem",
    publication_date=datetime.date(1845, 1, 1)
)

you can create translation for that instances like this:

> book.set_translation('es', 'title', 'El Cuervo')
> book.set_translation('es', 'description', 'El Cuervo es un poema narrativo')

a translation could be access individually:

> self.book.get_translation('es', 'title')
'El Cuervo'
> book.get_translation('es', 'description')
'El Cuervo es un poema narrativo'

or you can get all translations together:

> self.book.translations('es')
{
    'title': self.es_title,
    'description': self.es_description,
}

Installation:

pip install django-klingon

Running the Tests

You can run the tests with via:

python runtests.py

or:

tox

History

0.1.0 (2026-07-04)

Revival release — modernized for current Django/Python.

  • Added support for Django 4.2 LTS, 5.2 LTS, and 6.0; Python 3.10 through 3.14.
  • Fixed several long-standing compatibility breakages: ugettext (removed in Django 4.0), django.core.urlresolvers (removed), allow_tags (ignored since Django 3.0 — the admin translations link was silently rendering as escaped text), __unicode__ never called under Python 3.
  • Pinned default_auto_field to AutoField so Django 6.0's new BigAutoField default doesn't force an unrequested PK migration on existing installs.
  • Swapped the django-autoslug dependency for the maintained django-easy-autoslug fork.
  • Migrated packaging from setup.py to pyproject.toml, replaced Travis CI with GitHub Actions, and switched linting from flake8 to ruff.
  • Converted all documentation from reStructuredText to Markdown.
  • Fixed a stale-cache bug: translating the slug's source field (e.g. name) regenerated the slug translation row but left the old value in the per-field cache, so get_translation() kept returning the stale slug.
  • Fixed explicit slug translations being silently overwritten: calling set_translation() on the slug field itself no longer triggers auto-slug regeneration — the explicitly-set value now wins.
  • Translation cache keys are now app-qualified (app_label.model instead of the bare class name), so identically-named models in different apps can no longer collide. This changes the cache key format; pre-upgrade entries are simply never read again under the new keys and age out via the cache backend's normal eviction — no explicit flush is performed.
  • translate() and set_translation() on an unsaved instance now raise CanNotTranslate with a clear message instead of a database IntegrityError.
  • translate()/translations() no longer mutate translatable_fields to append the translatable_slug; the combined list is computed internally.
  • Translatable now uses pk instead of assuming an id attribute, so models with a custom-named integer primary key work.

0.0.7 (2017-1-7)

  • Removed support for Django 1.5 and 1.6 now klingon works from Django 1.7 version in advance

0.0.4 (2015-1-2)

  • Add translatable_slug and a painless integration with klingon + django-autoslug.

Metadata

Release files for django-klingon 0.1.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-klingon 0.1.0
File Size Uploaded Provenance Actions
django_klingon-0.1.0.tar.gz 22.0 kB Without provenance Details for django_klingon-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for django-klingon 0.1.0
File Interpreter ABI Platform Actions
django_klingon-0.1.0-py3-none-any.whl Python 3 none any Details for django_klingon-0.1.0-py3-none-any.whl

Total release size: 48.1 kB

Release files / django_klingon-0.1.0.tar.gz

Download URL django_klingon-0.1.0.tar.gz
Size 22.0 kB
Tags Source
SHA-256 checksum
How to use checksums
863411e2dfedbb211c5b45452dc90167c90a9de22257f41b4a214c51b4a43a40
BLAKE2b-256 checksum
How to use checksums
cf7d847d36bfa8eef4280f9a248a9a29b0c11ae680f8388641d69d64e8751d19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / django_klingon-0.1.0-py3-none-any.whl

Download URL django_klingon-0.1.0-py3-none-any.whl
Size 26.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2f5e1b400b6631ca28608dc41a74561093929f7690600d3a5775e97f567e97bf
BLAKE2b-256 checksum
How to use checksums
396a02afbdb6c5d8b5aef6d54989bc5775c2092851e702f31260b11f03398922
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for django-klingon 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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