Multi-language support in Django

14 views
Skip to first unread message

wang bin

unread,
Nov 22, 2005, 4:03:30 AM11/22/05
to django-d...@googlegroups.com
Currently Django only supports selecting a language based on the
browser's Accept-Language setting. Most web frameworks allows
overriding this setting with a cookie-based setting, so that you can
easily switch the language without changing the browser settings. Is
anyone working on this? If not, I can prepare a patch for this.

Is there a standard way to deal with multi-language models?
We've got models/ classes that have some information in several
languages, and we'd like to return an appropriate language, but
currently there's no easy way for the model to access the "current
language". What would be a good way? Again, is anyone working on
this?

hugo

unread,
Nov 22, 2005, 4:20:00 AM11/22/05
to Django developers
>Currently Django only supports selecting a language based on
> the browser's Accept-Language setting. Most web
> frameworks allows overriding this setting with a
> cookie-based setting, so that you can easily switch the
> language without changing the browser settings. Is anyone
> working on this? If not, I can prepare a patch for this.

http://www.djangoproject.com/documentation/i18n/#the-set-language-redirect-view

The chosen language is stored in request.LANGUAGE_CODE, so you can
access it in your view function and pass it along to model code that
needs to know it.

bye, Georg

Krzysztof Drozd

unread,
Nov 22, 2005, 8:31:19 AM11/22/05
to Django developers
i have some idee.

my model:
from django.core import meta
from django.conf.settings import LANGUAGES

class Publication(meta.Model):
pub_name = meta.CharField(maxlength=16,verbose_name='publication
name')
class META:
admin = meta.Admin()

class Site(meta.Model):
language = meta.CharField(maxlength=16,choices=LANGUAGES)
pub_conteiner= meta.ForeignKey(Publication,
edit_inline=meta.STACKED)
title = meta.CharField(maxlength=64,core=True)
site = meta.TextField(core=True)
pub_date = meta.DateTimeField()
class META:
admin = meta.Admin()
def __repr(self):
return self.title

in django admin i have a conteiner and OneTo Many Sites.

in template i'll use (this is not django code :)
for p in publication_list:
for site in site_list:
if s.lanuage == current_request.LANGUAGE
{{s.title}}<br>{{s.site}}...

this solution is ugly :)

django need a new meta.Model class with suport for i18n.
i need it so (backward-incompatibile change)
#------
from django.core import meta
from django.conf.settings import LANGUAGES

class Publication(meta.Model):
title = meta.CharField(maxlength=30,verbose_name=_('Title'))
conntent = meta.TextField(verbose_name=_('Content'))
class META:
admin = meta.Admin()
i18n_support = True
i18n_lang_list = LANGUAGES
i18n_default_lang = 'en'

and now in admin interface it shuld be one pos.on list and in detail
view it shuld
show LANGUAGES.count() forms to enter title and content
end in template like so

for pub in pub_list:
{{pub.title|request.LANGUAGE_CODE}}

or
for pub in pub_list:
{{pub.titel|i18n}}


sorry for my poor english :P

wang bin

unread,
Nov 22, 2005, 9:03:09 PM11/22/05
to django-d...@googlegroups.com
Thanks for reply, and hi Krzysztof Drozd I don't understand some code
you writed, could you please explain it, thanks. And also my english
is not good, if any offend please forgive me :)

2005/11/22, Krzysztof Drozd <krzy...@asi.pwr.wroc.pl>:


> class Publication(meta.Model):
> title = meta.CharField(maxlength=30,verbose_name=_('Title'))
> conntent = meta.TextField(verbose_name=_('Content'))
> class META:
> admin = meta.Admin()
> i18n_support = True
> i18n_lang_list = LANGUAGES
> i18n_default_lang = 'en'
>

How does the i18n_support, i18n_lang_list, i18n_default_lang works ?

Krzysztof Drozd

unread,
Nov 24, 2005, 8:02:24 AM11/24/05
to Django developers
:)
meybe so: if i18n_supprt is True then get_object_list shuld return
content (from DB) in only on language, this in request.LANGUAGE ? else
this = i18n_default_lang.

now i make my code so:
http://groups.google.com/group/django-developers/browse_thread/thread/37c0346fb9ba1cf7
#-*- coding: utf-8 -*-

from django.core import meta
from django.conf.settings import LANGUAGES

from django.conf.settings import GRUPY_ARTYKULOW

class Artykul(meta.Model):
publikowalny =
meta.BooleanField(default=True,verbose_name=_('Publikowalny'))
grupa = meta.CharField(
maxlength=36,
choices=GRUPY_ARTYKULOW,
verbose_name=_('Grupa artykulów'),
verbose_name_plural=_('Grupy artykulów'),
help_text=_('Wybierz grupe/kategorie artykulów')
)
nazwa = meta.CharField(
maxlength=64,
verbose_name=_('Nazwa artykulu'),
verbose_name_plural=_('Nazwy artykulów'),
help_text=_('Ten tytul bedzie pokazywac sie tylko w panelu
administracyjnym')
)
data_publikacji =
meta.DateTimeField(auto_now_add=True,verbose_name=_('Data publikacji'))
adres =
meta.SlugField(prepopulate_from=("nazwa",""),verbose_name=_('Adres URL
artykulu'))


class META:
admin = meta.Admin(

list_display =
('publikowalny','grupa','data_publikacji','nazwa'),
save_on_top=True,
search_fields = ('nazwa','grupa'),
)
get_lastest_by = "data_publikacji"
verbose_name = 'Artykul'
verbose_name_plural = 'Artykuly'
def __repr__(self):
return self.nazwa
def get_absolute_url(self):
return "/artykuly/%i" % (self.id)

class WersjaJezykowa(meta.Model):
artykul = meta.ForeignKey(
Artykul,
edit_inline=meta.STACKED,
num_in_admin=len(LANGUAGES),
num_extra_on_change=0
)
jezyk = meta.CharField(
maxlength=16,
choices=LANGUAGES,
radio_admin=True,
verbose_name=_('Jezyk'),
help_text=_('W tym polu mozesz wybrac jezyk strony')
)
tytul = meta.CharField(
maxlength=64,
core=True,
verbose_name=_('Tytul artykulu'),
help_text=_('Tytul artykulu, wpisz go we wlasciwym
jezyku')
)
tresc = meta.TextField(
core=True,
verbose_name=_('Tresc artykulu'),
help_text=_('Tresc artykulu, wpisz ja we wlasciwym
jezyku')


)
class META:
admin = meta.Admin()

verbose_name = 'Wersja jezykowa'
verbose_name_plural = 'Wersje jezykowe'
def __repr__(self):
return self.tytul
this is a simple multilang Article model class,
one site with multi languages, that will mayby work bu it is wery ugly
:)

Nebojša Đorđević - nesh

unread,
Nov 25, 2005, 4:47:53 AM11/25/05
to django-d...@googlegroups.com
On 24-11-2005, at 14:02, Krzysztof Drozd wrote:

> meybe so: if i18n_supprt is True then get_object_list shuld return
> content (from DB) in only on language, this in request.LANGUAGE ? else
> this = i18n_default_lang.

Here is my example model and helper function to get right translation
so you can in template do something like his {{ object.get_name }} or
{{ object.get_desc }} to get right translation for field name for the
current selected locale.

====================== model =====================

class Group(meta.Model):
""" grupe """

slug = meta.SlugField(_('short name'), maxlength=200, unique=True)

def __repr__(self):
return self.slug
#

def get_name(self):
""" get ml type name """
from contrib.i18n import get_for_lang
return get_for_lang(self.get_groupname, fallback=self.slug)
#
get_name.short_description = _('content group name')

def get_absolute_url(self):
import urlparse
return urlparse.urljoin(self.get_manufacturer
().get_absolute_url(), self.slug) + '/'
#

def get_desc(self):
""" get ml type desc """
from contrib.i18n import get_for_lang
return get_for_lang(self.get_groupdesc)
#
get_desc.short_description = _('content group description')

def get_name_trans(self):
return ' | '.join([n.locale.upper() for n in
self.get_groupname_list()])
#
get_name_trans.short_description = _('name translated for')

def get_desc_trans(self):
return ' | '.join([n.locale.upper() for n in
self.get_groupdesc_list()])
#
get_desc_trans.short_description = _('description translated for')

class META:
verbose_name = _('content group')
verbose_name_plural = _('content groups')

ordering = ['slug']
admin = meta.Admin(
list_display = ('get_name', 'slug',
'get_name_trans', 'get_desc_trans'),
)
# class
# Group

class GroupName(meta.Model):
group = meta.ForeignKey(Group, edit_inline=meta.TABULAR,
num_in_admin=len(LANGUAGES), max_num_in_admin=len
(LANGUAGES))
locale = meta.CharField(_('locale'), maxlength=10,
choices=LANGUAGES, db_index=True)
text = meta.CharField(_('name'), maxlength=200, core=True)

def __repr__(self):
return '[%s] %s' % (self.locale, self.text)

class META:
ordering = ['locale']
unique_together=(('group', 'locale'),)
# class
# GroupName

class GroupDesc(meta.Model):
group = meta.ForeignKey(Group, edit_inline=meta.TABULAR,
num_in_admin=len(LANGUAGES), max_num_in_admin=len
(LANGUAGES))
locale = meta.CharField(_('locale'), maxlength=10,
choices=LANGUAGES, db_index=True)
text = meta.TextField(_('description'),
help_text=_('Use <a href="http://
docutils.sourceforge.net/docs/user/rst/quickref.html"
target="_blank">reStructuredText</a>.'), core=True)

def __repr__(self):
return '[%s] %s' % (self.locale, self.text)

class META:
ordering = ['locale']
unique_together=(('group', 'locale'),)
# class
# GroupName

====================== model =====================
====================== get_for_lang =====================
def get_for_lang(func, fallback=None, locale_field='locale',
text_field='text', alt_loc=None):
""" get translation from db

func: function to call to get object
fallback: fallback text
locale_field: locale id field
text_field: text to return field
alt_loc: list of alternative locales, 'en' is added if not
present, if not defined use LANGUAGES
"""

locale = get_language()
kwargs = {'%s__exact' % locale_field: locale}

if fallback is None:
# ReSTish error message
class_name = func.im_class.__name__
obj = str(func.im_self)
fallback = _('''.. error:: MISSING TRANSLATION: no
translation for **%(locale)s**

function from ``%(class_name)s``, text field: ``%
(text_field)s``

Object: ``%(obj)s``
''') % locals()

text = None
cl = ''

# try preffered locale
try:
obj = func(**kwargs)
return getattr(obj, text_field)
except ObjectDoesNotExist:
pass

if alt_loc is None:
alt_loc = [loc[0] for loc in LANGUAGES]
elif not isinstance(alt_loc, (tuple, list)):
alt_loc = [alt_loc]
#
if 'en' not in alt_loc:
alt_loc.append('en')
#

for loc in alt_loc:
try:
kwargs = {'%s__exact' % locale_field: loc}
obj = func(**kwargs)
text = getattr(obj, text_field)
cl = loc
break
except ObjectDoesNotExist:
pass
# for

if (text is None) or (not text.strip()):
return fallback

return text
# get_for_lang

---
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]



Reply all
Reply to author
Forward
0 new messages