概要
- Django で I18N 対応 されたメッセージを取得しようとした時うまく取得できなかったという話
環境
確認した環境
- Mac OS X 10.11.5
- Python3.5
- Django1.9
前提
- Django で settingsの内容を下記のように設定する
LANGUAGE_CODE = 'ja'
USE_I18N = True
- 上記の様に設定すれば、I18N対応した日本語メッセージがあれば下記のようにして日本語のメッセージが取得できる。
from django.utils.translation import ugettext_lazy as _
_('Hello') # => こんにちわ
DjangoのCommandだと取得できない
- django-localflaover というパッケージがあって、ISO 3166-2:JP で定義された、日本の都道府県情報を取得できる。
- 都道府県名はI18N対応されていて、日本語名で都道県名が取得できる。
from localflavor.jp.jp_prefectures import JP_PREFECTURE_CODES
dict(JP_PREFECTURE_CODES)['13'] # => 東京都
- 上記をrunserverしたDjangoアプリから読んだりすると「東京都」という値が取得できる
- だが下記のようにDjangoのCommand内で呼ぶと、「Tokyo」が返ってくる
from django.core.management.base import BaseCommand
from localflavor.jp.jp_prefectures import JP_PREFECTURE_CODES
class Command(BaseCommand):
def handle(self, *args, **options):
print(dict(JP_PREFECTURE_CODES)['13']) # => Tokyo
- なんだよ!国際オリンピック委員会第8代会長 ジャック・ロゲ氏かよ!? と突っ込みたくなる一品。
なんで?
By default, the BaseCommand.execute() method deactivates translations
because some commands shipped with Django perform several tasks
(for example, user-facing content rendering and database population)
that require a project-neutral string language.
- アッ!ハイ!
- つまりDjangoのデフォルトのコマンド類が、translateされてると都合が悪いのでI18Nはオフになってるとのこと
- これは「manage.py shell」などのコマンドも同様です。
対応方法
- Commandのクラス変数に「leave_locale_alone=True」を付ければ良い。
from django.core.management.base import BaseCommand
from localflavor.jp.jp_prefectures import JP_PREFECTURE_CODES
class Command(BaseCommand):
leave_locale_alone = True
def handle(self, *args, **options):
print(dict(JP_PREFECTURE_CODES)['13']) # => 東京