This assumes you have followed the Installation guide.
django-localized-fields provides various model field types to store content in multiple languages. The most basic of them all is
LocalizedField which stores text of arbitrary length (like django.db.models.TextField).
Declaring a model¶
from localized_fields.models import LocalizedModel from localized_fields.fields import LocalizedField class MyModel(LocalizedModel): title = LocalizedField()
This creates a model with one localized field. Inside the
LocalizedField, strings can be stored in multiple languages. There are more fields like this for different data types (integers, images etc).
LocalizedField is the most basic of them all.
Saving localized content¶
You can now save text in
MyModel.title in all languages you defined in the LANGUAGES setting. A short example:
newobj = MyModel() newobj.title.en = "Hello" newobj.title.ar = "مرحبا" newobj.title.nl = "Hallo" newobj.save()
There are various other ways of saving localized content. For example, all fields can be set at once by assigning a
newobj = MyModel() newobj.title = dict(en="Hello", ar="مرحبا", nl="Hallo") newobj.save()
This also works when using the
newobj = MyModel.objects.create(title=dict(en="Hello", ar="مرحبا", nl="Hallo"))
Need to set the content dynamically? Use the
newobj = MyModel() newobj.title.set("en", "Hello")
Localized field values (
localized_fields.value.LocalizedValue) act like dictionaries. In fact,
dict. Anything that works on a
dict works on
Retrieving localized content¶
When querying, the currently active language is taken into account. If there is no active language set, the default language is returned (set by the LANGUAGE_CODE setting).
from django.utils import translation obj = MyModel.objects.first() print(obj.title) # prints "Hello" translation.activate("ar") print(obj.title) # prints "مرحبا" str(obj.title) # same as printing, forces translation to active language translation.activate("nl") print(obj.title) # prints "Hallo"
Use django.utils.translation.override to change the language for just a block of code rather than setting the language globally:
from django.utils import translation with translation.override("nl"): print(obj.title) # prints "Hallo"
If there is no content for the currently active language, a fallback kicks in where the content will be returned in the next language. The fallback order is controlled by the order set in the LANGUAGES setting.
obj = MyModel.objects.create(dict(en="Hallo", ar="مرحبا")) translation.activate("nl") print(obj.title) # prints "مرحبا" because there"s no content in NL
Use the LOCALIZED_FIELDS_FALLBACKS setting to control the fallback behaviour.
Cast to str¶
Want to get the value in the currently active language without casting to
str? (For null-able fields for example). Use the
obj = MyModel.objects.create(dict(en="Hallo", ar="مرحبا")) str(obj.title) == obj.title.translate() # True
str(..) is guarenteed to return a string. If the value is
str(..) returns an empty string.
translate() would return
None. This is because Python forces the
__str__ function to return a string.
obj = MyModel.objects.create(dict(en="Hallo")) translation.activate('nl') str(obj.title) # "" obj.title.translate() # None