or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-integration.mdcore-registration.mdfield-management.mdforms-integration.mdindex.mdquery-interface.mdutils-configuration.md

core-registration.mddocs/

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

```