Recently updated on
A few weeks ago I gave a talk at the Chicago Djangonauts meeting on Django Internationalization. Apparently this isn't a task that a lot of people need to do frequently, as the crowd was not too familiar with the content of the talk. Luckily, internationalization isn't too complicated a concept and it seemed that everyone took to the information comfortably.
When it comes down to it, internationalization is essentially a technique that replaces all strings in your application with an object that is evaluated at the last minute. When the object is evaluated, it looks up the actual string to use from your translation files.
This is called the GNU i18n GetText system and it stands as the most widely-used mechanism for software translations. You can read about GetText on Wikipedia; Django uses this for its own translations. The work consists of wrapping all of your strings in a GetText() call, then generating message files that you distribute to your translators. Once translators return the message files to you, you can place them in the appropriate place and Django will start serving translated versions of your site based on the browser-locale.
Luckily, there exists a project called Django-Rosetta that makes this second part of distributing and maintaining translated message files much simpler. It provides an administration interface where translators can do their translations right in the browser. A simple restart of the webserver and any provided translations become available immediately.
Astute readers may be wondering about translating actual database content. Fortunately, this too has been made very straightforward by the Django-Multilingual project. By having your models subclass from Multilingual's specialized model classes, you can maintain separate translations for all of your models right in the Django administration interface. If you use Django-CMS you will get this behavior for free for all of your CMS content, which is really quite nice.