django-klingon is an attempt to make django model translation suck but with no integrations pain in your app!
Project description
django-klingon
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_fieldtoAutoFieldso Django 6.0's newBigAutoFielddefault doesn't force an unrequested PK migration on existing installs. - Swapped the
django-autoslugdependency for the maintaineddjango-easy-autoslugfork. - Migrated packaging from
setup.pytopyproject.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, soget_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.modelinstead 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()andset_translation()on an unsaved instance now raiseCanNotTranslatewith a clear message instead of a databaseIntegrityError.translate()/translations()no longer mutatetranslatable_fieldsto append thetranslatable_slug; the combined list is computed internally.Translatablenow usespkinstead of assuming anidattribute, 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_klingon-0.1.0.tar.gz.
File metadata
- Download URL: django_klingon-0.1.0.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
863411e2dfedbb211c5b45452dc90167c90a9de22257f41b4a214c51b4a43a40
|
|
| MD5 |
679806eccc94f041012f150a51be5b82
|
|
| BLAKE2b-256 |
cf7d847d36bfa8eef4280f9a248a9a29b0c11ae680f8388641d69d64e8751d19
|
File details
Details for the file django_klingon-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_klingon-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f5e1b400b6631ca28608dc41a74561093929f7690600d3a5775e97f567e97bf
|
|
| MD5 |
243b8e323b9a188b43e1593c1b0ff00f
|
|
| BLAKE2b-256 |
396a02afbdb6c5d8b5aef6d54989bc5775c2092851e702f31260b11f03398922
|