hvad.models.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 hvad.models.TranslatedFields instance as related name.
In the database, two tables are created:
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 hvad.manager.FallbackManager.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_translations_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.
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).