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

field-management.mddocs/

0

# Field Management

1

2

Translation field types, descriptors, and factory functions for creating and managing multilingual model fields. Handles the dynamic creation of language-specific fields and their integration with Django's model system.

3

4

## Capabilities

5

6

### Translation Field Factory

7

8

Factory functions for dynamically creating translation fields based on original Django field types.

9

10

```python { .api }

11

def create_translation_field(model, field_name, lang, empty_value):

12

"""

13

Create a translation field for a specific language.

14

15

Parameters:

16

- model: Model class containing the original field

17

- field_name: Name of the original field to translate

18

- lang: Language code for this translation field

19

- empty_value: How to handle empty values ('', 'both', None, NONE)

20

21

Returns:

22

- TranslationField instance

23

24

Raises:

25

- ImproperlyConfigured: If field type is not supported

26

"""

27

28

def field_factory(baseclass):

29

"""

30

Create a translation field class based on Django field type.

31

32

Parameters:

33

- baseclass: Django field class to base translation field on

34

35

Returns:

36

- TranslationField subclass

37

"""

38

```

39

40

**Usage Example:**

41

42

```python

43

from modeltranslation.fields import create_translation_field

44

from myapp.models import Article

45

46

# Create French translation field for title

47

title_fr_field = create_translation_field(

48

model=Article,

49

field_name='title',

50

lang='fr',

51

empty_value=''

52

)

53

```

54

55

### Translation Field Base

56

57

Base class for all translation fields, providing common functionality and field proxying.

58

59

```python { .api }

60

class TranslationField:

61

"""

62

Base class for translation fields that proxy to original fields.

63

64

Attributes:

65

- translated_field: Original field being translated

66

- language: Language code for this translation

67

- empty_value: Empty value handling strategy

68

"""

69

70

def __init__(self, translated_field, language, empty_value):

71

"""

72

Initialize translation field.

73

74

Parameters:

75

- translated_field: Original Django field

76

- language: Language code (e.g., 'en', 'fr')

77

- empty_value: Empty value handling

78

"""

79

80

def contribute_to_class(self, cls, name):

81

"""Add this field to the model class."""

82

83

def formfield(self, **kwargs):

84

"""Create form field for this translation field."""

85

```

86

87

### Field Descriptors

88

89

Descriptors that handle field access and provide language-aware field behavior.

90

91

```python { .api }

92

class TranslationFieldDescriptor:

93

"""

94

Descriptor for accessing translation fields with language awareness.

95

Handles fallback logic and value resolution.

96

"""

97

98

def __init__(self, field):

99

"""

100

Initialize descriptor for translation field.

101

102

Parameters:

103

- field: TranslationField instance

104

"""

105

106

def __get__(self, instance, owner):

107

"""Get field value with language-aware fallback."""

108

109

def __set__(self, instance, value):

110

"""Set field value for current language."""

111

112

class TranslatedRelationIdDescriptor:

113

"""Descriptor for translated foreign key ID fields."""

114

115

class TranslatedManyToManyDescriptor:

116

"""Descriptor for translated many-to-many relationships."""

117

```

118

119

### Supported Field Types

120

121

Django field types that can be translated by modeltranslation.

122

123

```python { .api }

124

SUPPORTED_FIELDS: tuple = (

125

# Text fields

126

fields.CharField,

127

fields.TextField,

128

fields.json.JSONField,

129

130

# Numeric fields

131

fields.IntegerField,

132

fields.FloatField,

133

fields.DecimalField,

134

135

# Boolean fields

136

fields.BooleanField,

137

fields.NullBooleanField,

138

139

# Date/time fields

140

fields.DateField,

141

fields.DateTimeField,

142

fields.TimeField,

143

144

# File fields

145

fields.files.FileField,

146

fields.files.ImageField,

147

148

# Network fields

149

fields.IPAddressField,

150

fields.GenericIPAddressField,

151

152

# Relationship fields

153

fields.related.ForeignKey,

154

fields.related.ManyToManyField,

155

)

156

"""Tuple of Django field types supported for translation."""

157

```

158

159

**Custom Field Support:**

160

161

```python

162

# In Django settings.py

163

MODELTRANSLATION_CUSTOM_FIELDS = ('MyCustomField', 'AnotherField')

164

165

# Now MyCustomField can be used in translation

166

@register(MyModel)

167

class MyModelTranslationOptions(TranslationOptions):

168

fields = ('my_custom_field',) # Works if MyCustomField is in CUSTOM_FIELDS

169

```

170

171

### Empty Value Handling

172

173

Sentinel class and strategies for handling empty and undefined translation values.

174

175

```python { .api }

176

class NONE:

177

"""

178

Sentinel class for undefined translation values.

179

Used when fallback value is not yet known and needs computation.

180

"""

181

```

182

183

**Empty Value Strategies:**

184

185

```python

186

@register(Article)

187

class ArticleTranslationOptions(TranslationOptions):

188

fields = ('title', 'content', 'summary')

189

empty_values = {

190

'title': '', # Only empty string is considered empty

191

'content': 'both', # Both None and empty string are empty

192

'summary': None, # Only None is considered empty

193

}

194

```

195

196

### Field Attribute Management

197

198

Automatic handling of field attributes across translation fields.

199

200

```python

201

# Original field

202

class Article(models.Model):

203

title = models.CharField(max_length=255, help_text="Article title")

204

content = models.TextField(blank=True, null=True)

205

206

# After registration, translation fields inherit attributes:

207

# title_en = CharField(max_length=255, help_text="Article title (English)")

208

# title_fr = CharField(max_length=255, help_text="Article title (French)")

209

# content_en = TextField(blank=True, null=True)

210

# content_fr = TextField(blank=True, null=True)

211

```

212

213

### Relationship Field Translation

214

215

Special handling for foreign key and many-to-many field translations.

216

217

```python { .api }

218

# For ForeignKey fields

219

class TranslatedRelationIdDescriptor:

220

"""

221

Handles translated foreign key relationships.

222

Manages the _id suffix and related object access.

223

"""

224

225

# For ManyToManyField fields

226

class TranslatedManyToManyDescriptor:

227

"""

228

Handles translated many-to-many relationships.

229

Creates intermediate models for each language.

230

"""

231

```

232

233

**Relationship Translation Example:**

234

235

```python

236

class Article(models.Model):

237

title = models.CharField(max_length=255)

238

category = models.ForeignKey(Category, on_delete=models.CASCADE)

239

tags = models.ManyToManyField(Tag)

240

241

@register(Article)

242

class ArticleTranslationOptions(TranslationOptions):

243

fields = ('title', 'category', 'tags')

244

245

# Creates fields:

246

# title_en, title_fr, title_de

247

# category_en, category_fr, category_de (ForeignKey fields)

248

# tags_en, tags_fr, tags_de (ManyToMany fields with intermediate models)

249

```

250

251

### Field Validation

252

253

Translation field validation and constraint handling.

254

255

```python

256

class CustomTranslationField(TranslationField):

257

def validate(self, value, model_instance):

258

"""Custom validation for translation field."""

259

super().validate(value, model_instance)

260

261

# Add custom validation logic

262

if value and len(value) < 5:

263

raise ValidationError("Translation must be at least 5 characters")

264

265

def clean(self, value, model_instance):

266

"""Clean and prepare field value."""

267

value = super().clean(value, model_instance)

268

269

# Add custom cleaning logic

270

if isinstance(value, str):

271

value = value.strip()

272

273

return value

274

```

275

276

## Advanced Usage

277

278

### Dynamic Field Creation

279

280

Programmatically create translation fields at runtime.

281

282

```python

283

from modeltranslation.fields import create_translation_field

284

285

def add_translation_field(model, field_name, language):

286

"""Dynamically add translation field to model."""

287

trans_field = create_translation_field(

288

model=model,

289

field_name=field_name,

290

lang=language,

291

empty_value=''

292

)

293

294

localized_name = f"{field_name}_{language}"

295

trans_field.contribute_to_class(model, localized_name)

296

297

return trans_field

298

```

299

300

### Custom Field Descriptors

301

302

Create custom descriptors for specialized translation behavior.

303

304

```python

305

class CustomTranslationDescriptor:

306

def __init__(self, field_name, language):

307

self.field_name = field_name

308

self.language = language

309

310

def __get__(self, instance, owner):

311

if instance is None:

312

return self

313

314

# Custom logic for getting translated value

315

return getattr(instance, f"{self.field_name}_{self.language}", None)

316

317

def __set__(self, instance, value):

318

# Custom logic for setting translated value

319

setattr(instance, f"{self.field_name}_{self.language}", value)

320

```

321

322

### Field Migration Support

323

324

Handle field migrations when adding or modifying translations.

325

326

```python

327

# Migration support for adding translation fields

328

from django.db import migrations

329

from modeltranslation.fields import TranslationField

330

331

class Migration(migrations.Migration):

332

operations = [

333

migrations.AddField(

334

model_name='article',

335

name='title_fr',

336

field=TranslationField(original_field='title', language='fr'),

337

),

338

]

339

```

340

341

### Performance Optimization

342

343

Optimize field access and memory usage for translation fields.

344

345

```python

346

class OptimizedTranslationDescriptor:

347

def __init__(self, field):

348

self.field = field

349

self._cache_key = f"_{field.name}_cache"

350

351

def __get__(self, instance, owner):

352

if instance is None:

353

return self

354

355

# Use caching to improve performance

356

cache_key = self._cache_key

357

if hasattr(instance, cache_key):

358

return getattr(instance, cache_key)

359

360

value = self._get_translated_value(instance)

361

setattr(instance, cache_key, value)

362

return value

363

```