Djangoでサイトの利用者ごとに翻訳の言語設定を切り替える

Djangoで、サイトの利用者ごとに言語設定を切り替えたい。
DjangoはセッションやCOOKIEの値を参照して、どの言語に翻訳するかを決める仕組みをミドルウェアで提供している。
言語設定の検出メカニズム - 翻訳 ― Django 1.4 documentation
フォームから送信された内容を使って、言語設定を変更してみる。
試したバージョンは、Django1.6、Python3.3。

サンプルコード

コード例を部分的に紹介。

myapp/views.py

translation.activateを使うと、リクエスト中で使用する言語を切り替えられる。
セッションのdjango_languageというキーに言語の文字(jaとか)を入れると、LocaleMiddlewareで参照されて言語が切り替わる。

from django.shortcuts import render
from django.utils import translation
from . import forms

def index(request):
    form = forms.SwitchLanguageForm(request.POST or None)
    if form.is_valid():
        lang = form.cleaned_data['language']
        # リクエスト中の言語設定切り替え
        translation.activate(lang)
        # セッションの言語設定切り替え
        request.session['django_language'] = lang
    return render(request, 'index.html', {'form': form})
myapp/forms.py
from django import forms
from django.conf import settings

class SwitchLanguageForm(forms.Form):
    language = forms.ChoiceField(choices=settings.LANGUAGES, required=True)
myapp/templates/index.html

テキストを翻訳するtransタグを使用する場合はi18nをロードする。
Djangoのadminに含まれてる"User"や"Save"の文字列を翻訳してみる。

{% load i18n %}
<html>
<body>
<h1>{% trans "User" %}</h1>
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">{% trans "Save" %}</button>
</form>
</body>
</html>
switch_language_proj/settings.py(抜粋)

ドキュメントにも書かれているが、ミドルウェアの位置には注意する(SessionMiddlwwareの後ろ、CommonMiddlewareの前)。
LANGUAGESの表示を翻訳する場合はugettext_lazyを使う。

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',  # アプリを有効化
)   

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # ここに追加
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

from django.utils.translation import ugettext_lazy
LANGUAGES = (
    ('ja', ugettext_lazy('Japanese')),
    ('en', ugettext_lazy('English')),
    ('zh', ugettext_lazy('Simplified Chinese')),
)

実行結果