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')), )