Guide: Context¶
This module provides an in depth knowledge of the Translations context.
Important
The examples are assumed to CRUD this dataset.
Type\Lang |
English |
German |
---|---|---|
Continent |
Europe |
Europa |
Asia |
Asien |
|
Country |
Germany |
Deutschland |
South Korea |
Südkorea |
|
City |
Cologne |
Köln |
Seoul |
Seul |
Please memorize this dataset in order to understand the examples better.
What is context¶
When something is going to be stated it can be done so in the context of a certain language.
Initialize a context¶
To initialize a context use the Context
class.
The instances to be affected by the context must be defined in the
initialization, meaning which entity and what relations of it
should the context act upon. This is called the context’s purview.
All the actions like reading the translations, updating the translations, etc only affects the objects in the defined purview.
To initialize a context for an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
# initialize context
with Context(europe, *relations) as context:
print('Context initialized!')
Context initialized!
To initialize a context for a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
# initialize context
with Context(continents, *relations) as context:
print('Context initialized!')
Context initialized!
To initialize a context for a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
# initialize context
with Context(continents, *relations) as context:
print('Context initialized!')
Context initialized!
The entity must be a model instance, a queryset or a list of model instances. The model of the entity must be translatable.
Each relation may be divided into separate parts
by __
s to represent a deeply nested relation.
Each part must be a related_name
.
The models of the relations must be
translatable.
Note
It is recommended for the relations of the entity to be prefetched before initializing a context, in order to reach optimal performance.
To do this use
select_related
,
prefetch_related
or
prefetch_related_objects
.
Creating the translations¶
To create the translations of the context’s purview in a language
use the create()
method.
This creates the translations using the translatable fields of the context’s purview.
It accepts a language code which determines the language to
create the translation in.
To create the translations of an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
with Context(europe, *relations) as context:
# change the instance like before
europe.name = 'Europa'
europe.countries.all()[0].name = 'Deutschland'
europe.countries.all()[0].cities.all()[0].name = 'Köln'
# create the translations in German
context.create('de')
print('Translations created!')
Translations created!
To create the translations of a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# change the queryset like before
continents[0].name = 'Europa'
continents[0].countries.all()[0].name = 'Deutschland'
continents[0].countries.all()[0].cities.all()[0].name = 'Köln'
# create the translations in German
context.create('de')
print('Translations created!')
Translations created!
To create the translations of a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# change the list of instances like before
continents[0].name = 'Europa'
continents[0].countries.all()[0].name = 'Deutschland'
continents[0].countries.all()[0].cities.all()[0].name = 'Köln'
# create the translations in German
context.create('de')
print('Translations created!')
Translations created!
The language code must already be declared in the
LANGUAGES
setting. It is optional and if it is
not passed in, it is automatically set to the active language code.
Creating duplicate translations for a field raises
IntegrityError
, to update the translations check out
updating the translations.
Note
Creating only affects the translatable fields that have changed.
If the value of a field is not changed, the translation for it is not created. (No need to set all the translatable fields beforehand)
Reading the translations¶
To read the translations of the context’s purview in a language
use the read()
method.
This reads the translations onto the translatable fields of the context’s purview.
It accepts a language code which determines the language to
read the translation in.
To read the translations of an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
with Context(europe, *relations) as context:
# read the translations in German
context.read('de')
# use the instance like before
print(europe)
print(europe.countries.all())
print(europe.countries.all()[0].cities.all())
Europa
<TranslatableQuerySet [
<Country: Deutschland>,
]>
<TranslatableQuerySet [
<City: Köln>,
]>
To read the translations of a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# read the translations in German
context.read('de')
# use the queryset like before
print(continents)
print(continents[0].countries.all())
print(continents[0].countries.all()[0].cities.all())
<TranslatableQuerySet [
<Continent: Asien>,
<Continent: Europa>,
]>
<TranslatableQuerySet [
<Country: Deutschland>,
]>
<TranslatableQuerySet [
<City: Köln>,
]>
To read the translations of a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# read the translations in German
context.read('de')
# use the list of instances like before
print(continents)
print(continents[0].countries.all())
print(continents[0].countries.all()[0].cities.all())
[
<Continent: Europa>,
<Continent: Asien>,
]
<TranslatableQuerySet [
<Country: Deutschland>,
]>
<TranslatableQuerySet [
<City: Köln>,
]>
The language code must already be declared in the
LANGUAGES
setting. It is optional and if it is
not passed in, it is automatically set to the active language code.
Note
Reading only affects the translatable fields that have a translation.
If there is no translation for a field, the value of the field is not changed. (It remains what it was before)
Warning
Any methods on the relations queryset which imply a database query will reset previously translated results:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.prefetch_related(
'countries',
)
with Context(continents, 'countries') as context:
context.read('de')
# querying after translation
print(continents[0].countries.exclude(name=''))
<TranslatableQuerySet [
<Country: Germany>,
]>
In some cases the querying can be done before the translation:
from django.db.models import Prefetch
from translations.context import Context
from sample.models import Continent, Country
# querying before translation
continents = Continent.objects.prefetch_related(
Prefetch(
'countries',
queryset=Country.objects.exclude(name=''),
),
)
with Context(continents, 'countries') as context:
context.read('de')
print(continents[0].countries.all())
<TranslatableQuerySet [
<Country: Deutschland>,
]>
Updating the translations¶
To update the translations of the context’s purview in a language
use the update()
method.
This updates the translations using the translatable fields of the context’s purview.
It accepts a language code which determines the language to
update the translation in.
To update the translations of an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
with Context(europe, *relations) as context:
# change the instance like before
europe.name = 'Europa (changed)'
europe.countries.all()[0].name = 'Deutschland (changed)'
europe.countries.all()[0].cities.all()[0].name = 'Köln (changed)'
# update the translations in German
context.update('de')
print('Translations updated!')
Translations updated!
To update the translations of a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# change the queryset like before
continents[0].name = 'Europa (changed)'
continents[0].countries.all()[0].name = 'Deutschland (changed)'
continents[0].countries.all()[0].cities.all()[0].name = 'Köln (changed)'
# update the translations in German
context.update('de')
print('Translations updated!')
Translations updated!
To update the translations of a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# change the list of instances like before
continents[0].name = 'Europa (changed)'
continents[0].countries.all()[0].name = 'Deutschland (changed)'
continents[0].countries.all()[0].cities.all()[0].name = 'Köln (changed)'
# update the translations in German
context.update('de')
print('Translations updated!')
Translations updated!
The language code must already be declared in the
LANGUAGES
setting. It is optional and if it is
not passed in, it is automatically set to the active language code.
Note
Updating only affects the translatable fields that have changed.
If the value of a field is not changed, the translation for it is not updated. (No need to initialize all the translatable fields beforehand)
Deleting the translations¶
To delete the translations of the context’s purview in a language
use the delete()
method.
This deletes the translations for the translatable fields of the context’s purview.
It accepts a language code which determines the language to
delete the translation in.
To delete the translations of an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
with Context(europe, *relations) as context:
# delete the translations in German
context.delete('de')
print('Translations deleted!')
Translations deleted!
To delete the translations of a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# delete the translations in German
context.delete('de')
print('Translations deleted!')
Translations deleted!
To delete the translations of a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# delete the translations in German
context.delete('de')
print('Translations deleted!')
Translations deleted!
The language code must already be declared in the
LANGUAGES
setting. It is optional and if it is
not passed in, it is automatically set to the active language code.
Resetting the translations¶
To reset the translations of the context’s purview to the default language
use the reset()
method.
This resets the translations on the translatable fields of the context’s purview.
To reset the translations of an instance and some relations of it:
from translations.context import Context
from sample.models import Continent
europe = Continent.objects.get(code='EU')
relations = ('countries', 'countries__cities',)
with Context(europe, *relations) as context:
# changes happened to the fields, create, read, update, delete, etc...
context.read('de')
# reset the translations
context.reset()
# use the instance like before
print(europe)
print(europe.countries.all())
print(europe.countries.all()[0].cities.all())
Europe
<TranslatableQuerySet [
<Country: Germany>,
]>
<TranslatableQuerySet [
<City: Cologne>,
]>
To reset the translations of a queryset and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = Continent.objects.all()
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# changes happened to the fields, create, read, update, delete, etc...
context.read('de')
# reset the translations
context.reset()
# use the queryset like before
print(continents)
print(continents[0].countries.all())
print(continents[0].countries.all()[0].cities.all())
<TranslatableQuerySet [
<Continent: Asia>,
<Continent: Europe>,
]>
<TranslatableQuerySet [
<Country: Germany>,
]>
<TranslatableQuerySet [
<City: Cologne>,
]>
To reset the translations of a list of instances and some relations of it:
from translations.context import Context
from sample.models import Continent
continents = list(Continent.objects.all())
relations = ('countries', 'countries__cities',)
with Context(continents, *relations) as context:
# changes happened to the fields, create, read, update, delete, etc...
context.read('de')
# reset the translations
context.reset()
# use the list of instances like before
print(continents)
print(continents[0].countries.all())
print(continents[0].countries.all()[0].cities.all())
[
<Continent: Europe>,
<Continent: Asia>,
]
<TranslatableQuerySet [
<Country: Germany>,
]>
<TranslatableQuerySet [
<City: Cologne>,
]>