Metadata-Version: 2.4
Name: django-klingon
Version: 0.1.0
Summary: django-klingon is an attempt to make django model translation suck but with no integrations pain in your app!
Author-email: "Rafael Capdevielle, Angel Velasquez" <angvp@archlinux.org>
License: GPL
Project-URL: Homepage, http://github.com/angvp/django-klingon
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Development Status :: 4 - Beta
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: AUTHORS.md
Requires-Dist: Django<7.0,>=4.2
Provides-Extra: autoslug
Requires-Dist: django-easy-autoslug; extra == "autoslug"
Dynamic: license-file

<img src="django-klingon-logo.png" alt="django-klingon" width="200">

# django-klingon

[![Tests](https://github.com/angvp/django-klingon/actions/workflows/tests.yml/badge.svg)](https://github.com/angvp/django-klingon/actions/workflows/tests.yml)
[![Coverage](https://codecov.io/gh/angvp/django-klingon/branch/master/graph/badge.svg)](https://codecov.io/gh/angvp/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:

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

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

```python
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:

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

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

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

your model should look like this:

```python
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](https://github.com/mireq/django-autoslugfield)'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:

```python
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:

```python
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:

```python
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:

```python
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:

```python
> 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:

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

a translation could be access individually:

```python
> 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:

```python
> 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.
