Source code for translations.models
"""This module contains the models for the Translations app."""
from django.db import models
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, \
GenericRelation
try:
from django.utils.translation import ugettext_lazy as _
except ImportError:
from django.utils.translation import gettext_lazy as _
from translations.querysets import TranslatableQuerySet
__docformat__ = 'restructuredtext'
[docs]class Translation(models.Model):
"""The model which represents the translations."""
content_type = models.ForeignKey(
verbose_name=_('content type'),
help_text=_('the content type of the object to translate'),
to=ContentType,
on_delete=models.CASCADE,
)
object_id = models.CharField(
verbose_name=_('object id'),
help_text=_('the id of the object to translate'),
max_length=128,
)
content_object = GenericForeignKey(
ct_field='content_type',
fk_field='object_id',
)
field = models.CharField(
verbose_name=_('field'),
help_text=_('the field of the object to translate'),
max_length=64,
)
language = models.CharField(
verbose_name=_('language'),
help_text=_('the language of the translation'),
max_length=32,
choices=settings.LANGUAGES,
)
text = models.TextField(
verbose_name=_('text'),
help_text=_('the text of the translation'),
)
def __str__(self):
"""Return the representation of the translation."""
return '{source}: {translation}'.format(
source=getattr(self.content_object, self.field),
translation=self.text,
)
class Meta:
unique_together = ('content_type', 'object_id', 'field', 'language',)
verbose_name = _('translation')
verbose_name_plural = _('translations')
[docs]class Translatable(models.Model):
"""An abstract model which provides custom translation functionalities."""
objects = TranslatableQuerySet.as_manager()
translations = GenericRelation(
Translation,
content_type_field='content_type',
object_id_field='object_id',
related_query_name='%(app_label)s_%(class)s',
)
class Meta:
abstract = True
[docs] @classmethod
def get_translatable_fields(cls):
"""Return the model’s translatable fields."""
if not hasattr(cls, '_cached_translatable_fields'):
if cls.TranslatableMeta.fields is None:
fields = []
for field in cls._meta.get_fields():
if isinstance(
field,
(models.CharField, models.TextField,)
) and not isinstance(
field,
models.EmailField
) and not (
hasattr(field, 'choices') and field.choices
):
fields.append(field)
else:
fields = [
cls._meta.get_field(field_name)
for field_name in cls.TranslatableMeta.fields
]
cls._cached_translatable_fields = fields
return cls._cached_translatable_fields
[docs] @classmethod
def _get_translatable_fields_names(cls):
"""Return the names of the model's translatable fields."""
if not hasattr(cls, '_cached_translatable_fields_names'):
cls._cached_translatable_fields_names = [
field.name for field in cls.get_translatable_fields()
]
return cls._cached_translatable_fields_names
[docs] @classmethod
def _get_translatable_fields_choices(cls):
"""Return the choices of the model's translatable fields."""
choices = [
(None, '---------'),
]
for field in cls.get_translatable_fields():
choice = (field.name, field.verbose_name.title())
choices.append(choice)
return choices