General information on django-hvad internals¶
How it works¶
Model Definition¶
Function hvad.models.prepare_translatable_model()
is invoked by Django
metaclass using class_prepared
signal. It
scans all attributes on the model defined for instances of
hvad.models.TranslatedFields
, and if it finds one, sets the respective
options onto meta.
TranslatedFields
both creates the
Translations Model and makes a foreign key from that model to point to
the Shared Model which has the name of the attribute of the
TranslatedFields
instance as related name.
In the database, two tables are created:
- The table for the Shared Model with the normal Django way of defining the table name.
- The table for the Translations Model, which if not specified otherwise
in the options (meta) of the Translations Model will have the name of
the database table of the Shared Model suffixed by
_translations
as database table name.
Queries¶
The main idea of django-hvad is that when you query the Shared Model
using the Django ORM, what actually happens behind the scenes (in the queryset)
is that it queries the Translations Model and selects the relation to
the Shared Model. This means that model instances can only be queried if
they have a translation in the language queried in, unless an alternative
manager is used, for example by using
untranslated()
.
Due to the way the Django ORM works, this approach does not seem to be possible
when querying from a Normal Model, even when using
hvad.utils.get_translation_aware_manager()
and therefore in that case we
just add extra filters to limit the lookups to rows in the database where the
Translations Model row existist in a specific language, using
<translations_accessor>__language_code=<current_language>
. This is
suboptimal since it means that we use two different ways to query translations
and should be changed if possible to use the same technique like when a
Translated Model is queried.
A word on caching¶
Throughout this documentation, caching of translations is mentioned a lot. By
this we don’t mean proper caching using the Django cache framework, but rather
caching the instance of the Translations Model on the instance of the
Shared Model for easier access. This is done by setting the instance of
the Translations Model on the attribute defined by the
translations_cache
on the Shared Model’s options (meta).