akiyoko blog

akiyoko の IT技術系ブログです

Django 5.0 で削除された「USE_L10N」とは何だったのか? そして今後はどうなるのか?

この投稿は 「Djangoのカレンダー | Advent Calendar 2023 - Qiita」 15日目の記事です。

小ネタです。


Django 5.0 で「USE_L10N」が削除されました。

https://docs.djangoproject.com/ja/5.0/releases/5.0/#features-removed-in-5-0 より



そもそも Django には「USE_I18N 」と「USE_L10N」という設定があり、その変数名からそれぞれが「国際化 (internationalization) 」と「ローカル化 (localization) 」に対応するかと思いきや、Django においては、「USE_I18N 」は言語設定に合わせたテキストの多言語対応、「USE_L10N」は言語設定に合わせた日時や数字のフォーマット対応を扱います。 これらの変数の微妙なネーミングには歴史的な経緯があるとのこと。

国際化 (internationalization)
ソフトウェアをローカル化に備えさせることです。通常、開発者によって行われます。
ローカル化 (localization)
翻訳およびローカルな表示形式を記述することです。通常、翻訳者によって行われます。


Translation is controlled by the USE_I18N setting. However, it involves internationalization and localization. The name of the setting is an unfortunate result of Django's history.
(翻訳はUSE_I18N設定によって制御されます。しかし、これは国際化とローカライゼーションに関わります。この設定の名前は Django の歴史が生んだ不幸な結果です。)


https://docs.djangoproject.com/ja/5.0/topics/i18n/ より



なお、多言語対応については、芝田さんの「実践Django Pythonによる本格Webアプリケーション開発」に詳しく書かれているのでぜひどうぞ。

あとは、公式ドキュメントの 翻訳 | Django ドキュメント | Django あたりをご参照ください。




本題に入ります。

Django 4.2 まで使われている「USE_L10N」は、先に述べた通り、言語設定に合わせた日時や数字の表示形式を扱うための設定です。

もっと具体的に言えば、主にテンプレートに変数を表示する際、変数が数値型・日時型・日付型・時刻型の場合に、「USE_L10N」と「LANGUAGE_CODE」の設定内容にしたがったフォーマット変換をしてくれる設定 ということになります。


もちろん、管理サイトのモデル一覧画面などの表示にも適用されます。




Django 4.2 以前は、「USE_L10N」は次のように動作します。

「USE_L10N」が False の場合、設定ファイルの「DATETIME_FORMAT」や「DATE_FORMAT」のフォーマットに変換される(設定が無ければ、global_settings.py のデフォルトのフォーマットに従って変換される)。


「USE_L10N」が True の場合、(設定ファイルや global_settings.py のフォーマット設定に関係なく)「LANGUAGE_CODE」で指定した言語ごとのフォーマットに変換される。


「LANGUAGE_CODE」で指定した言語ごとのフォーマットというのは、「conf/locale/ja/」のようにロケールごとに置かれた「formats.py」に書かれたフォーマットを指します。例えば、日本語の場合は次に示す formats.py がデフォルトで用意されています。

django/conf/locale/ja/formats.py

# This file is distributed under the same license as the Django package.
#
# The *_FORMAT strings use the Django date format syntax,
# see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
DATE_FORMAT = "Y年n月j日"
TIME_FORMAT = "G:i"
DATETIME_FORMAT = "Y年n月j日G:i"
YEAR_MONTH_FORMAT = "Y年n月"
MONTH_DAY_FORMAT = "n月j日"
SHORT_DATE_FORMAT = "Y/m/d"
SHORT_DATETIME_FORMAT = "Y/m/d G:i"
# FIRST_DAY_OF_WEEK =

# The *_INPUT_FORMATS strings use the Python strftime format syntax,
# see https://docs.python.org/library/datetime.html#strftime-strptime-behavior
# DATE_INPUT_FORMATS =
# TIME_INPUT_FORMATS =
# DATETIME_INPUT_FORMATS =
DECIMAL_SEPARATOR = "."
THOUSAND_SEPARATOR = ","
NUMBER_GROUPING = 3


Django 5.0 以降で「USE_L10N」が削除されますが、言語設定に合わせて日時や数字の表示フォーマットを変更できなくなるわけではありません。「USE_L10N」が常に True 扱いになったと考えればよいだけです。 ご安心ください。


Django 5.0 以降で日時や数字の表示フォーマットをデフォルトのものから変更するには、Django 4.2 以前と同じように「FORMAT_MODULE_PATH」*1 を使って、言語に合わせた formats.py のフォーマット設定を書き換えてあげればよいです。


(ディレクトリ構成例)

.
|-- conf
|   |-- __init__.py
|   `-- locale
|       |-- __init__.py
|       `-- ja
|           |-- __init__.py
|           `-- formats.py
|-- config
|   |-- __init__.py
|   |-- asgi.py
|   |-- settings.py
|   |-- test.py
|   |-- urls.py
|   |-- views.py
|   `-- wsgi.py
・
・


config/settings.py

LANGUAGE_CODE = 'ja'

FORMAT_MODULE_PATH = 'conf.locale'

(Django 5.0 以降では「USE_L10N」の設定は不要です。むしろ、設定してもまったく意味がありません。)


conf/locale/ja/formats.py

DATE_FORMAT = 'Y-m-d'
DATETIME_FORMAT = 'Y-m-d H:i'