CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-modeltranslation

Translates Django models using a registration approach without modifying original model classes.

Pending
Overview
Eval results
Files

core-registration.mddocs/

Core Registration

The foundation of django-modeltranslation's translation system. Provides decorators and classes for registering Django models to enable field translation without modifying original model definitions.

Capabilities

Model Registration

Register Django models for translation using the decorator pattern, similar to Django's admin registration.

def register(model_or_iterable, **options):
    """
    Decorator for registering model(s) with translation options.
    
    Parameters:
    - model_or_iterable: Model class or iterable of model classes
    - **options: Additional registration options
    
    Returns:
    - Decorator function that accepts TranslationOptions subclass
    
    Raises:
    - AlreadyRegistered: If model is already registered
    - DescendantRegistered: If descendant model is already registered
    """

Usage Example:

from modeltranslation.translator import register, TranslationOptions
from myapp.models import Article, Category

@register(Article)
class ArticleTranslationOptions(TranslationOptions):
    fields = ('title', 'content', 'summary')

# Register multiple models at once
@register([Category, Article])
class MultipleTranslationOptions(TranslationOptions):
    fields = ('name', 'description')

Translation Options

Base class for defining which fields should be translatable and configuring translation behavior.

class TranslationOptions:
    """Base class for defining translation field options."""
    
    fields: tuple = ()
    """Tuple of field names to make translatable."""
    
    empty_values: dict | None = None
    """Dict mapping field names to empty values."""
    
    required_languages: tuple | None = None
    """Languages required for these fields."""
    
    fallback_languages: dict | None = None
    """Custom fallback languages for these fields."""
    
    fallback_values: str | None = None
    """Fallback value handling strategy."""
    
    fallback_undefined: str | None = None
    """Handling for undefined fallback values."""

Configuration Options:

@register(News)
class NewsTranslationOptions(TranslationOptions):
    fields = ('title', 'content')
    empty_values = {
        'title': 'both',  # Allow both None and empty string
        'content': ''     # Only empty string is considered empty
    }
    required_languages = ('en', 'fr')  # These languages are required
    fallback_languages = {
        'default': ('en',),
        'fr': ('en', 'de')
    }

Translator Management

Central translator instance that manages model registrations and provides access to translation options.

class Translator:
    """Main translator class managing model registrations."""
    
    def register(self, model_or_iterable, opts_class, **options):
        """
        Register model(s) with translation options.
        
        Parameters:
        - model_or_iterable: Model class or iterable of models
        - opts_class: TranslationOptions subclass
        - **options: Additional options
        """
    
    def unregister(self, model_or_iterable):
        """
        Unregister model(s) from translation.
        
        Parameters:
        - model_or_iterable: Model class or iterable of models
        """
    
    def get_options_for_model(self, model):
        """
        Get translation options for a model.
        
        Parameters:
        - model: Model class
        
        Returns:
        - TranslationOptions instance
        
        Raises:
        - NotRegistered: If model is not registered
        """
    
    def get_registered_models(self):
        """
        Get all registered models.
        
        Returns:
        - List of registered model classes
        """
    
    def is_registered(self, model):
        """
        Check if model is registered for translation.
        
        Parameters:
        - model: Model class
        
        Returns:
        - bool: True if registered
        """

translator: Translator
"""Global translator instance for managing registrations."""

Usage Example:

from modeltranslation.translator import translator

# Check if model is registered
if translator.is_registered(MyModel):
    options = translator.get_options_for_model(MyModel)
    print(f"Translatable fields: {options.fields}")

# Get all registered models
registered = translator.get_registered_models()
print(f"Registered models: {[m.__name__ for m in registered]}")

Field Inheritance

Translation fields are inherited from parent classes, allowing for flexible model hierarchies.

# Base model with translations
@register(BaseContent)
class BaseContentTranslationOptions(TranslationOptions):
    fields = ('title', 'description')

# Child model automatically inherits parent translations
class Article(BaseContent):
    content = models.TextField()
    author = models.CharField(max_length=100)

@register(Article)
class ArticleTranslationOptions(TranslationOptions):
    fields = ('content', 'author')  # In addition to inherited fields

Registration Validation

The registration system validates configuration and prevents common errors.

class AlreadyRegistered(Exception):
    """Raised when attempting to register an already registered model."""

class NotRegistered(Exception):
    """Raised when accessing options for unregistered model."""

class DescendantRegistered(Exception):
    """Raised when child model is registered before parent."""

Error Handling:

from modeltranslation.translator import AlreadyRegistered, NotRegistered

try:
    translator.get_options_for_model(UnregisteredModel)
except NotRegistered:
    print("Model is not registered for translation")

try:
    @register(MyModel)
    class DuplicateOptions(TranslationOptions):
        fields = ('name',)
except AlreadyRegistered:
    print("Model is already registered")

Advanced Usage

Custom Empty Values

Configure how empty values are handled for different field types:

@register(Product)
class ProductTranslationOptions(TranslationOptions):
    fields = ('name', 'description', 'price')
    empty_values = {
        'name': 'both',      # Both None and '' are empty
        'description': '',   # Only '' is empty
        'price': None        # Only None is empty
    }

Language-Specific Configuration

Define different fallback strategies per language:

@register(Article)
class ArticleTranslationOptions(TranslationOptions):
    fields = ('title', 'content')
    fallback_languages = {
        'default': ('en',),           # Default fallback to English
        'fr': ('en', 'de'),          # French falls back to English, then German
        'es': ('en',),               # Spanish falls back to English
    }
    required_languages = ('en', 'fr')  # These languages must have values

Registration Discovery

Django-modeltranslation automatically discovers translation.py modules in installed apps, similar to Django's admin autodiscovery. This happens when the app is ready and can be controlled via settings.

# In your app's translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import MyModel

@register(MyModel)
class MyModelTranslationOptions(TranslationOptions):
    fields = ('title', 'description')

Install with Tessl CLI

npx tessl i tessl/pypi-django-modeltranslation

docs

admin-integration.md

core-registration.md

field-management.md

forms-integration.md

index.md

query-interface.md

utils-configuration.md

tile.json