Holger Sielaff holger

django-translatable-fields (0.1.1)

Published 2025-08-04 17:40:46 +02:00 by holger

Installation

pip install --index-url  --extra-index-url https://pypi.org/ django-translatable-fields

About this package

Django plugin that mimics Odoo's translate=True functionality with admin interface integration

Django Translatable Fields

PyPI version Python versions Django versions License

A Django plugin that mimics Odoo's translate=True functionality, providing automatic language-aware field handling with a beautiful admin interface integration.

Features

  • 🌍 Language-Aware Fields: Automatic translation handling based on Django's current language
  • 📝 Rich Admin Interface: Modal overlay with WYSIWYG editor for easy translation management
  • 🗄️ JSON Storage: Efficient storage of translations in a single database column
  • 🔧 Easy Integration: Drop-in replacement for Django's standard fields
  • 🎨 Draggable & Resizable: Modern modal interface with drag and resize capabilities
  • 🚀 DRF Support: Built-in Django REST Framework serializers for API development
  • Field Validation: Proper validation for Email, URL, and Slug fields per language
  • 🎯 Type Safety: Full support for Django's field types with translation capabilities

Quick Start

1. Installation

pip install django-translatable-fields

Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ... other apps
    'django_translatable_fields',
]

2. Define Your Model

from django.db import models
from django_translatable_fields.fields import CharField, TextField, EmailField, URLField, SlugField
from django_translatable_fields.descriptors import TranslatableModelMixin

class Product(TranslatableModelMixin, models.Model):
    name = CharField(max_length=200, translatable=True)
    description = TextField(translatable=True)
    slug = SlugField(max_length=200, translatable=True)
    support_email = EmailField(translatable=True)
    website = URLField(translatable=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    
    def __str__(self):
        return self.name

3. Configure Admin

from django.contrib import admin
from django_translatable_fields.admin import TranslatableModelAdmin
from .models import Product

@admin.register(Product)
class ProductAdmin(TranslatableModelAdmin):
    list_display = ['name', 'slug', 'price']
    fields = ['name', 'description', 'slug', 'support_email', 'website', 'price']
    prepopulated_fields = {'slug': ('name',)}

4. Usage

from django.utils.translation import activate

# Create a product
product = Product.objects.create(
    name="Awesome Product",
    description="This is an amazing product",
    slug="awesome-product",
    support_email="support@example.com",
    website="https://example.com",
    price=29.99
)

# Set translations for all fields
product.name_en = "Awesome Product"
product.name_de = "Fantastisches Produkt"
product.name_fr = "Produit Fantastique"

product.description_en = "This is an amazing product"
product.description_de = "Das ist ein fantastisches Produkt"
product.description_fr = "C'est un produit fantastique"

product.slug_en = "awesome-product"
product.slug_de = "fantastisches-produkt"
product.slug_fr = "produit-fantastique"

product.support_email_en = "support@example.com"
product.support_email_de = "support@beispiel.de"
product.support_email_fr = "support@exemple.fr"

product.website_en = "https://example.com"
product.website_de = "https://beispiel.de"
product.website_fr = "https://exemple.fr"

product.save()

# Language-aware access
activate('en')
print(product.name)        # "Awesome Product"
print(product.slug)        # "awesome-product"
print(product.website)     # "https://example.com"

activate('de')
print(product.name)        # "Fantastisches Produkt"
print(product.slug)        # "fantastisches-produkt"
print(product.website)     # "https://beispiel.de"

activate('fr')
print(product.name)        # "Produit Fantastique"
print(product.slug)        # "produit-fantastique"
print(product.website)     # "https://exemple.fr"

# Get all translations for any field
name_translations = product.get_all_translations('name')
print(name_translations)   # {'en': 'Awesome Product', 'de': 'Fantastisches Produkt', 'fr': 'Produit Fantastique'}

url_translations = product.get_all_translations('website')
print(url_translations)    # {'en': 'https://example.com', 'de': 'https://beispiel.de', 'fr': 'https://exemple.fr'}

Admin Interface

The plugin provides an Odoo-style admin interface:

  • Primary Field: Shows the default language (English) input field
  • Translate Button: Click the translate icon (🌐) next to any translatable field
  • Modal Overlay: Opens a modal with input fields for all configured languages
  • Clean Interface: Only the primary language is visible initially, keeping the interface clean

Just like in Odoo, the translate functionality is accessed through a button next to each translatable field, opening an overlay with all language versions.

Configuration

Configure your languages in Django settings:

LANGUAGES = [
    ('en', 'English'),
    ('de', 'German'),
    ('fr', 'French'),
    ('es', 'Spanish'),
]

API Reference

Fields

  • CharField: Like Django's CharField but with translatable=True parameter
  • TextField: Like Django's TextField but with translatable=True parameter
  • EmailField: Like Django's EmailField but with translatable=True parameter
  • URLField: Like Django's URLField but with translatable=True parameter
  • SlugField: Like Django's SlugField but with translatable=True parameter

Both fields accept a translatable=True parameter (default: True).

Model Methods

When using TranslatableModelMixin:

  • obj.field_name: Returns value in current language
  • obj.field_name_en: Returns English translation
  • obj.get_translation(field_name, language_code): Get specific translation
  • obj.set_translation(field_name, language_code, value): Set specific translation
  • obj.get_all_translations(field_name): Get all translations as dict

Admin Classes

  • TranslatableModelAdmin: Use instead of ModelAdmin for automatic widget handling
  • TranslatableAdminMixin: Mixin for custom admin classes

Storage Format

Translations are stored as JSON in the database:

{
  "en": "Hello World",
  "de": "Hallo Welt", 
  "fr": "Bonjour le monde"
}

Requirements

  • Django >= 3.2
  • Python >= 3.8

License

MIT License

Requirements

Requires Python: >=3.9
Details
PyPI
2025-08-04 17:40:46 +02:00
15
MIT License Copyright (c) 2024 Holger Sielaff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
78 KiB
Assets (2)
Versions (4) View all
0.1.3 2025-08-04
0.1.2 2025-08-04
0.1.1 2025-08-04
0.1.0 2025-08-04