0
# Core Registration
1
2
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.
3
4
## Capabilities
5
6
### Model Registration
7
8
Register Django models for translation using the decorator pattern, similar to Django's admin registration.
9
10
```python { .api }
11
def register(model_or_iterable, **options):
12
"""
13
Decorator for registering model(s) with translation options.
14
15
Parameters:
16
- model_or_iterable: Model class or iterable of model classes
17
- **options: Additional registration options
18
19
Returns:
20
- Decorator function that accepts TranslationOptions subclass
21
22
Raises:
23
- AlreadyRegistered: If model is already registered
24
- DescendantRegistered: If descendant model is already registered
25
"""
26
```
27
28
**Usage Example:**
29
30
```python
31
from modeltranslation.translator import register, TranslationOptions
32
from myapp.models import Article, Category
33
34
@register(Article)
35
class ArticleTranslationOptions(TranslationOptions):
36
fields = ('title', 'content', 'summary')
37
38
# Register multiple models at once
39
@register([Category, Article])
40
class MultipleTranslationOptions(TranslationOptions):
41
fields = ('name', 'description')
42
```
43
44
### Translation Options
45
46
Base class for defining which fields should be translatable and configuring translation behavior.
47
48
```python { .api }
49
class TranslationOptions:
50
"""Base class for defining translation field options."""
51
52
fields: tuple = ()
53
"""Tuple of field names to make translatable."""
54
55
empty_values: dict | None = None
56
"""Dict mapping field names to empty values."""
57
58
required_languages: tuple | None = None
59
"""Languages required for these fields."""
60
61
fallback_languages: dict | None = None
62
"""Custom fallback languages for these fields."""
63
64
fallback_values: str | None = None
65
"""Fallback value handling strategy."""
66
67
fallback_undefined: str | None = None
68
"""Handling for undefined fallback values."""
69
```
70
71
**Configuration Options:**
72
73
```python
74
@register(News)
75
class NewsTranslationOptions(TranslationOptions):
76
fields = ('title', 'content')
77
empty_values = {
78
'title': 'both', # Allow both None and empty string
79
'content': '' # Only empty string is considered empty
80
}
81
required_languages = ('en', 'fr') # These languages are required
82
fallback_languages = {
83
'default': ('en',),
84
'fr': ('en', 'de')
85
}
86
```
87
88
### Translator Management
89
90
Central translator instance that manages model registrations and provides access to translation options.
91
92
```python { .api }
93
class Translator:
94
"""Main translator class managing model registrations."""
95
96
def register(self, model_or_iterable, opts_class, **options):
97
"""
98
Register model(s) with translation options.
99
100
Parameters:
101
- model_or_iterable: Model class or iterable of models
102
- opts_class: TranslationOptions subclass
103
- **options: Additional options
104
"""
105
106
def unregister(self, model_or_iterable):
107
"""
108
Unregister model(s) from translation.
109
110
Parameters:
111
- model_or_iterable: Model class or iterable of models
112
"""
113
114
def get_options_for_model(self, model):
115
"""
116
Get translation options for a model.
117
118
Parameters:
119
- model: Model class
120
121
Returns:
122
- TranslationOptions instance
123
124
Raises:
125
- NotRegistered: If model is not registered
126
"""
127
128
def get_registered_models(self):
129
"""
130
Get all registered models.
131
132
Returns:
133
- List of registered model classes
134
"""
135
136
def is_registered(self, model):
137
"""
138
Check if model is registered for translation.
139
140
Parameters:
141
- model: Model class
142
143
Returns:
144
- bool: True if registered
145
"""
146
147
translator: Translator
148
"""Global translator instance for managing registrations."""
149
```
150
151
**Usage Example:**
152
153
```python
154
from modeltranslation.translator import translator
155
156
# Check if model is registered
157
if translator.is_registered(MyModel):
158
options = translator.get_options_for_model(MyModel)
159
print(f"Translatable fields: {options.fields}")
160
161
# Get all registered models
162
registered = translator.get_registered_models()
163
print(f"Registered models: {[m.__name__ for m in registered]}")
164
```
165
166
### Field Inheritance
167
168
Translation fields are inherited from parent classes, allowing for flexible model hierarchies.
169
170
```python
171
# Base model with translations
172
@register(BaseContent)
173
class BaseContentTranslationOptions(TranslationOptions):
174
fields = ('title', 'description')
175
176
# Child model automatically inherits parent translations
177
class Article(BaseContent):
178
content = models.TextField()
179
author = models.CharField(max_length=100)
180
181
@register(Article)
182
class ArticleTranslationOptions(TranslationOptions):
183
fields = ('content', 'author') # In addition to inherited fields
184
```
185
186
### Registration Validation
187
188
The registration system validates configuration and prevents common errors.
189
190
```python { .api }
191
class AlreadyRegistered(Exception):
192
"""Raised when attempting to register an already registered model."""
193
194
class NotRegistered(Exception):
195
"""Raised when accessing options for unregistered model."""
196
197
class DescendantRegistered(Exception):
198
"""Raised when child model is registered before parent."""
199
```
200
201
**Error Handling:**
202
203
```python
204
from modeltranslation.translator import AlreadyRegistered, NotRegistered
205
206
try:
207
translator.get_options_for_model(UnregisteredModel)
208
except NotRegistered:
209
print("Model is not registered for translation")
210
211
try:
212
@register(MyModel)
213
class DuplicateOptions(TranslationOptions):
214
fields = ('name',)
215
except AlreadyRegistered:
216
print("Model is already registered")
217
```
218
219
## Advanced Usage
220
221
### Custom Empty Values
222
223
Configure how empty values are handled for different field types:
224
225
```python
226
@register(Product)
227
class ProductTranslationOptions(TranslationOptions):
228
fields = ('name', 'description', 'price')
229
empty_values = {
230
'name': 'both', # Both None and '' are empty
231
'description': '', # Only '' is empty
232
'price': None # Only None is empty
233
}
234
```
235
236
### Language-Specific Configuration
237
238
Define different fallback strategies per language:
239
240
```python
241
@register(Article)
242
class ArticleTranslationOptions(TranslationOptions):
243
fields = ('title', 'content')
244
fallback_languages = {
245
'default': ('en',), # Default fallback to English
246
'fr': ('en', 'de'), # French falls back to English, then German
247
'es': ('en',), # Spanish falls back to English
248
}
249
required_languages = ('en', 'fr') # These languages must have values
250
```
251
252
### Registration Discovery
253
254
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.
255
256
```python
257
# In your app's translation.py
258
from modeltranslation.translator import register, TranslationOptions
259
from .models import MyModel
260
261
@register(MyModel)
262
class MyModelTranslationOptions(TranslationOptions):
263
fields = ('title', 'description')
264
```