django-modeltrans icon indicating copy to clipboard operation
django-modeltrans copied to clipboard

Per-record default language

Open bbliem opened this issue 2 years ago • 0 comments

So far, modeltrans assumed that the value of an original field (a translatable field when used without a language suffix; for example title, but not title_nl) is in the Django default language, which is the one specified by the setting LANGUAGE_CODE. Translations to any other language will be stored in the model's implicitly generated JSON field.

In some cases, it may be desired to use per-record default languages instead of a single global default language. For example, for a model for organizations from different parts of the world, each instance has a name that is in the respective local language and it may be desired to use this local-language name by default instead of storing it in the JSON field and leaving the original field empty for potentially many instances.

This PR adds an argument default_language_field to TranslationField that allows users to refer to a field that specifies the language of the original field. The default language field can be either in the same instance or in another reachable via foreign keys using the __ syntax.

Example:

class Organization(models.Model):
    name = models.CharField(max_length=255)
    language = models.CharField(max_length=2)
    i18n = TranslationField(fields=("name",), default_language_field="language")

class Department(models.Model):
    name = models.CharField(max_length=255)
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
    i18n = TranslationField(fields=("name",), default_language_field="organization__language")

Now, no matter the LANGUAGE_CODE setting, for both of the following instances the name field will contain the local name and the JSON field i18n will be empty:

amsterdam = Organization.objects.create(name="Gemeente Amsterdam", language="nl")
helsinki = Organization.objects.create(name="Helsingin kaupunki", language="fi")

In addition, the names are also available in amsterdam.name_nl and helsinki.name_fi.

Please see the documentation for this feature (docs/pages/working-with-models.rst) for some caveats.

In particular, changing the default language is not supported at the moment because it's nontrivial when __ is used in default_language_field, but if there is interest in that I could try writing some code for that as well.

I also found what could be considered a bug in modeltrans (issue #84). So far, the current PR fixes it when default_language_field is used, but it doesn't change the behavior when default_language_field is not used in order to keep the behavior the same for existing applications. Perhaps it would be a good idea to make this the default behavior, however.

I'm happy to receive feedback and make some changes if needed.

bbliem avatar Aug 24 '22 11:08 bbliem