Edited at

Django のコマンドは USE_I18N を無視するという話

More than 3 years have passed since last update.


概要


  • 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.

refs https://docs.djangoproject.com/ja/1.9/howto/custom-management-commands/#management-commands-and-locales



  • アッ!ハイ!

  • つまり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']) # => 東京


参考