How to do it...

Execute the following steps to define the multilingual character field and multilingual text field:

  1. Open the fields.py file and create the base multilingual field, as follows:
# utils/fields.py
from django.conf import settings
from django.db import models
from django.utils.translation import get_language


class MultilingualField(models.Field):
SUPPORTED_FIELD_TYPES = [models.CharField, models.TextField]

def __init__(self, verbose_name=None, **kwargs):
self.localized_field_model = None
for model in MultilingualField.SUPPORTED_FIELD_TYPES:
if issubclass(self.__class__, model):
self.localized_field_model = model
self._blank = kwargs.get("blank", False)
self._editable = kwargs.get("editable", True)
super().__init__(verbose_name, **kwargs)

@staticmethod
def localized_field_name(name, lang_code):
lang_code_safe = lang_code.replace("-", "_")
return f"{name}_{lang_code_safe}"

def get_localized_field(self, lang_code, lang_name):
_blank = (self._blank
if lang_code == settings.LANGUAGE_CODE
else True)
localized_field = self.localized_field_model(
f"{self.verbose_name} ({lang_name})",
name=self.name,
primary_key=self.primary_key,
max_length=self.max_length,
unique=self.unique,
blank=_blank,
null=False, # we ignore the null argument!
db_index=self.db_index,
default=self.default or "",
editable=self._editable,
serialize=self.serialize,
choices=self.choices,
help_text=self.help_text,
db_column=None,
db_tablespace=self.db_tablespace)
return localized_field

def contribute_to_class(self, cls, name,
private_only=False,
virtual_only=False):
def translated_value():
language = get_language()
val = self.__dict__.get(
MultilingualField.localized_field_name(
name, language))
if not val:
val = self.__dict__.get(
MultilingualField.localized_field_name(
name, settings.LANGUAGE_CODE))
return val

# generate language-specific fields dynamically
if not cls._meta.abstract:
if self.localized_field_model:
for lang_code, lang_name in settings.LANGUAGES:
localized_field = self.get_localized_field(
lang_code, lang_name)
localized_field.contribute_to_class(
cls,
MultilingualField.localized_field_name(
name, lang_code))
setattr(cls, name, property(translated_value))
else:
super().contribute_to_class(
cls, name, private_only, virtual_only)
  1. In the same file, subclass the base field for character and text field forms, as follows:
class MultilingualCharField(models.CharField, MultilingualField):
pass


class MultilingualTextField(models.TextField, MultilingualField):
pass

Now, we'll consider an example of how to use the multilingual fields in your app, as follows:

  1. First, set multiple languages in the settings for your project:
# settings.py or config/base.py
LANGUAGE_CODE = "en-us"

LANGUAGES = (
("en-us", "US English"),
("en-gb", "British English"),
("de", "Deutsch"),
("fr", "Français"),
("lt", "Lietuvių kalba"),
)
  1. Then, open the models.py file from the demo_app and create the multilingual fields for the Idea model, as follows:
# demo_app/models.py
from django.db import models
from django.utils.translation import ugettext_lazy as _

from utils.fields import (
MultilingualCharField,
MultilingualTextField)

class Idea(models.Model):
class Meta:
verbose_name = _("Idea")
verbose_name_plural = _("Ideas")

title = MultilingualCharField(_("Title"),
max_length=200)
description = MultilingualTextField(_("Description"),
blank=True)
content = models.MultilingualTextField(_("Content"))

def __str__(self):
return self.title
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.13.173