Another helper function which I use often to get language dependent
objects from database. I think that's this case is common enough to
put support for that in the framework (see below).
---- code ----
from django.utils.translation import get_language
from django.core.exceptions import ObjectDoesNotExist
def get_for_lang(func, fallback='no translation',
lang_field='locale', text_field='text', alt_lang=[]):
""" get translation from db
func: function to call to get object
fallback: fallback text
lang_field: locale id field
text_field: text to return field
alt_lang: list of alternative locales, 'en' is added if not
present
"""
kwargs = {'%s__exact' % lang_field: get_language()}
text = None
# try preferred language
try:
obj = func(**kwargs)
return getattr(obj, text_field)
except ObjectDoesNotExist:
pass
if not isinstance(alt_lang, (tuple, list)):
alt_lang = [alt_lang]
#
if 'en' not in alt_lang:
alt_lang.append('en')
#
for lng in alt_lang:
try:
kwargs = {'%s__exact' % lang_field: lng}
obj = func(**kwargs)
text = getattr(obj, text_field)
break
except ObjectDoesNotExist:
pass
# for
if text is None:
return fallback
return text
# get_for_lang
--------
OTOH, maybe is better to add new I18NCharField and I18NTextField
(with better names than mine ;) ) to models to support this common
case. I don't know enough about models to make that myself, but in
time ... :)
Example:
class Article(meta.Model):
model_no = CharField(...)
price = FloatField(...)
...
name = I18NCharField(maxlength=200)
description = I18NTextField()
def __repr__(self):
return self.get_name()
this will create additional models like this:
class ArticleName(meta.Model):
article = meta.ForeignKey(Article, edit_inline=meta.TABULAR,
num_in_admin=len(LANGUAGES), max_num_in_admin=len
(LANGUAGES))
locale = meta.CharField(maxlength=10, choices=LANGUAGES,
db_index=True)
name = meta.CharField(maxlength=200, core=True)
def __repr__(self):
return '[%s] %s' % (self.locale, self.name)
class META:
ordering = ['locale']
unique_together=(('article', 'locale'),)
# class
# ArticleName
class ArticleDescription(meta.Model):
article = meta.ForeignKey(Article, edit_inline=meta.TABULAR,
num_in_admin=len(LANGUAGES), max_num_in_admin=len
(LANGUAGES))
locale = meta.CharField(maxlength=10, choices=LANGUAGES,
db_index=True)
description = meta.TextField(core=True)
def __repr__(self):
return '[%s] %s' % (self.locale, self.description)
class META:
ordering = ['locale']
unique_together=(('article', 'locale'),)
# class
# ArticleName
and also add this functions to the Article model: get_name() and get_
description() which will return appropriate heading or body field
(i.e. using get_for_lang from above) from object based on current
selected language.
I'm found while writing current application that this pattern is very
common (almost a 2/3 of my models are using some type of localized
name/description fields) and it will be great that i18n/model
framework supports that without any additional code.
Any thoughts?
---
Nebojša Đorđević - nesh
Studio Quattro - Niš - SCG
http://djnesh.blogspot.com/ | http://djnesh-django.blogspot.com/
Registered Linux User 282159 [http://counter.li.org]