Internationalization (i18n) of model: request.LANGUAGE_CODE in __unicode__ and ordering?

41 views
Skip to first unread message

Wouter van der Graaf

unread,
May 7, 2009, 10:55:31 AM5/7/09
to Django users
Hi there,

Spent hours trying to find the solution, but no luck. So here goes...

Please consider simplified code below:

{{{
class Country(models.Model):
...
label_en = models.CharField(max_length = 128, blank=True,
null=True)
label_nl = models.CharField(max_length = 128, blank=True,
null=True)

class Meta:
ordering = ('label_en',)

def __unicode__(self):
if hasattr(settings, 'LANGUAGE_CODE'):
field = 'label_%s' % settings.LANGUAGE_CODE.lower()
if hasattr(self, field):
return getattr(self, field)
return self.label_en
}}}

Other models use Country with a ForeignKey relationship. The
__unicode__ function works for displaying localized country names. If
LANGUAGE_CODE is 'nl' then the drop down selectbox for Country in the
admin shows Dutch country names, otherwise all country names are
English.

But it's not exactly what you'd want. Now I want to be able to do two
things:

1. Change __unicode__ to use request.LANGUAGE_CODE, the user
preference.
2. Change ordering to the chosen language field. You don't want a
list in Dutch, ordered by English translations.

All this is happening runtime, of course. Users in a admin edit page,
using a drop down for the foreign key Country, should see the country
names and ordering change when they select another language.

Possible? Other ways to achieve a runtime language dependent model?

Thanks in advance,

Wouter

Tom Evans

unread,
May 7, 2009, 3:46:18 PM5/7/09
to django...@googlegroups.com

IMHO, that is very definitely the wrong way to do i18n! I say this from
a position of authority, as I have had to maintain systems like this in
the past, and it is just Plain Wrong :)

i18n is a very tricky topic, fortunately very smart people have spent a
long long time to come up with the best solution - gettext. It is
builtin to python, and is well supported by django. Read more about it
here:

http://docs.djangoproject.com/en/dev/topics/i18n/#topics-i18n

Your scenario is slightly more complicated than the examples shown
there, but the principle is the same. Instead of having separate fields
for each language translation, your field holds the key phrase which is
then used to lookup the correct translation in a gettext catalog.

Your change to your model would look like this:

class Country(models.Model):
description = models.CharField(...)

def __unicode__(self):
return ugettext_lazy(self.description)

I'm afraid this isn't a magic bullet though, for two reasons:

1) Your main aim seems to be to allow natural language ordering? I'm not
entirely sure how one could achieve that, as the ordering is done as
part of the DB query, which would not have access to the gettext catalog
- any ideas anyone?

2) As you add more instances of your model, you would need to be able to
add the translation of the description to the gettext catalog. This
might be fine in this specific case (how many countries will be
dynamically added later?), but wouldn't be for something slightly more
dynamic, like tag names. Again, any ideas anyone?

i18n, l10n and collation are pet peeves of mine, I am still yet to find
excellent solutions to all of these problems :)

Cheers

Tom

Wouter van der Graaf

unread,
May 11, 2009, 6:59:03 AM5/11/09
to Django users
Hi Tom,

Thanks for sharing your thoughts. Indeed, I need ordering based on the
translations. If I'd use gettext for database field record
translations, then ordering must be done afterwards (after db query).
Is that even possible and what would be the performance cost?

And how could I tell the admin site (in my ModelAdmin or ModelForm
subclasses) to change the ordering to the natural language of the
translated list?

My Country model isn't the only one that has fields that need be
translated. Another (dynamic) model has thousands of entries and every
entry has a description field that needs to be translated. I've not
yet begun working on this, as I'm still looking at possibilities. Are
there no cons of using gettext for thousands of descriptions in ten
languages? Are there no limits?

Using gettext all the way would mean updating the po catalog with
every addition, removal or update of an entry. This can be done using
polib (http://code.google.com/p/polib/). The edit form on the admin
site would have to be enhanced with translation form fields for every
translatable model field. Or maybe Rosetta (http://code.google.com/p/
django-rosetta/) is all the tooling I need?

Cheers,

Wouter

Wouter van der Graaf

unread,
May 20, 2009, 4:04:29 AM5/20/09
to Django users
Hope this subject gets some more exposure. I'm curious to know what is
possible in using gettext for all dynamic database translations.

Or should I wait till Marc Garcia has finished work on his Google
Summer Of Code i18n project (http://vaig.be/2009/04/gsoc-
implementation-of-additional-i18n.html)? My guess is that he will use
a database driven approach to translating database field content, not
gettext.

Finally, will his solution be able to change the ordering of a model
to the natural language chosen by the user (request.LANGUAGE_CODE)?

Kai Kuehne

unread,
May 20, 2009, 4:19:53 AM5/20/09
to django...@googlegroups.com
On Thu, May 7, 2009 at 4:55 PM, Wouter van der Graaf <wou...@dynora.nl> wrote:
>
> Hi there,
>
> Spent hours trying to find the solution, but no luck. So here goes...

I have worked on making django-countries working with 1.1:
http://github.com/kaikuehne/django-countries/tree/master

There's also a branch which uses django-multilingual which I created
but not published. If you'd need that, I could polish it and put in on
github too.

Wouter van der Graaf

unread,
May 20, 2009, 7:16:01 AM5/20/09
to Django users
On 20 mei, 10:19, Kai Kuehne <kai.kue...@gmail.com> wrote:

> I have worked on making django-countries working with 1.1:http://github.com/kaikuehne/django-countries/tree/master
>
> There's also a branch which uses django-multilingual which I created
> but not published. If you'd need that, I could polish it and put in on
> github too.

Hi Kai,

If your app changes the default ordering of the country list to the
language in request.LANGUAGE_CODE (the user specified language) then
that's a good option for me.

Cheers,

Wouter

Kai Kuehne

unread,
May 20, 2009, 7:38:53 AM5/20/09
to django...@googlegroups.com
Hi,

On Wed, May 20, 2009 at 1:16 PM, Wouter van der Graaf <wou...@dynora.nl> wrote:
> If your app changes the default ordering of the country list to the
> language in request.LANGUAGE_CODE (the user specified language) then
> that's a good option for me.

It uses django-multilingual which itself uses the default language set
by django:
http://docs.djangoproject.com/en/dev/topics/i18n/#id2

Reply all
Reply to author
Forward
0 new messages