__title__ = 'slim.models.__init__'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = 'Copyright (c) 2013-2014 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('Slim', 'SlimBaseModel')
from six import PY2
from django.db import models
from django.utils.translation import ugettext_lazy as _
from slim import get_languages, default_language, get_languages_keys
from slim.translations import is_primary_language
from slim.helpers import admin_change_url, admin_add_url
[docs]class Slim(object):
"""
Add this class to all your multi-lingual Django models, where you use ``slim.models.fields.LanguageField``.
Alternatively, you may use the ``slim.models.SlimBaseModel``.
"""
@property
[docs] def is_multilingual(self):
"""
Simple flat to use on objects to find our wheither they are multilinugal
or not
:return bool: Always returns boolean True
"""
return True
[docs] def get_redirect_to_target(self, request):
"""
Find an acceptable redirect target. If this is a local link, then try
to find the page this redirect references and translate it according
to the user's language. This way, one can easily implement a localized
"/"-url to welcome page redirection.
"""
target = self.redirect_to
if target and target.find('//') == -1: # Not an offsite link http://bla/blubb
try:
page = cls.objects.page_for_path(target)
page = page.get_translation(getattr(request, 'LANGUAGE_CODE', None))
target = page.get_absolute_url()
except cls.DoesNotExist:
pass
return target
[docs] def available_translations(self):
"""
Returns available translations.
:return interable: At this moment a list of objects.
"""
if not self.id: # New, unsaved pages have no translations
return []
if is_primary_language(self.language):
return self.translations.all()
elif self.translation_of:
return [self.translation_of] + list(self.translation_of.translations.exclude(
language=self.language))
else:
return []
[docs] def get_original_translation(self, *args, **kwargs):
"""
Gets original translation of current object.
:return obj: Object of the same class as the one queried.
"""
if is_primary_language(self.language):
return self
return self.translation_of
[docs] def translation_admin(self, *args, **kwargs):
"""
Gets a HTML with URL to the original translation of available. For admin use.
:return str:
"""
if self.translation_of:
if PY2:
url_title = unicode(self.translation_of)
else:
url_title = self.translation_of
return admin_change_url(
self._meta.app_label,
self._meta.module_name,
self.translation_of.id,
url_title = url_title
)
return ''
translation_admin.allow_tags = True
translation_admin.short_description = _('Translation of')
def _available_translations_admin(self, include_self=True):
"""
Gets a HTML with all available translation URLs for current object if available. For admin use.
:return str:
"""
try:
original_translation = self.original_translation
available_translations = list(self.available_translations())
languages_keys = get_languages_keys()
languages = dict(get_languages())
if include_self:
available_translations.append(self)
output = []
# Processing all available translations. Adding edit links.
if available_translations:
for translation in available_translations:
if PY2:
url_title = unicode(languages[translation.language])
else:
url_title = languages[translation.language]
output.append(
admin_change_url(
translation._meta.app_label,
translation._meta.module_name,
translation.id,
url_title = url_title
)
)
languages_keys.remove(translation.language)
if self.pk and self.language in languages_keys:
languages_keys.remove(self.language)
# For all languages that are still available (original object has no translations for)
for language in languages_keys:
url = admin_add_url(
self._meta.app_label,
self._meta.module_name,
'?translation_of=%s&language=%s' % (str(original_translation.id), language)
)
if PY2:
name = unicode(languages[language])
else:
name = languages[language]
output.append(u'<a href="%(url)s" style="color:#baa">%(name)s</a>' % {'url': url, 'name': name})
return u' | '.join(output)
except Exception as e:
return u''
[docs] def available_translations_admin(self, *args, **kwargs):
"""
Gets a HTML with all available translation URLs for current object if available. For admin use.
:return str:
"""
return self._available_translations_admin(include_self=True, *args, **kwargs)
available_translations_admin.allow_tags = True
available_translations_admin.short_description = _('Translations')
[docs] def available_translations_exclude_current_admin(self, *args, **kwargs):
"""
Same as `available_translations_admin` but does not include itself to the list.
:return str:
"""
return self._available_translations_admin(include_self=False, *args, **kwargs)
available_translations_exclude_current_admin.allow_tags = True
available_translations_exclude_current_admin.short_description = _('Translations')
@property
[docs] def original_translation(self):
"""
Property for ``get_original_translation`` method.
:return obj: Object of the same class as the one queried.
"""
return self.get_original_translation()
[docs] def get_translation_for(self, language):
"""
Get translation article in given language.
:param str language: Which shall be one of the languages specified in ``LANGUAGES``
in `settings.py`.
:return obj: Either object of the same class as or None if no translations are
available for the given ``language``.
"""
if not language in get_languages_keys():
return None
if str(self.language) == str(language):
return self
if str(self.original_translation.language) == str(language):
return self.original_translation
try:
return self.original_translation.translations.get(language=language)
except Exception as e:
return None
[docs]class SlimBaseModel(models.Model, Slim):
"""
An abstract Django model.
"""