組込エンジニアだって Python/Django

投稿者: | 2015年11月8日

Needed half a day to resolve a locale issue of Django.

久々の日記です。徒然草を読んだり、地下に潜ったり、しばらく組込技術から離れてました。

さて。IoT とデータベース技術の統合を目指している訳ではないのですが、最近 Django をいじっています。大抵の問題は、いまやググると数分で解決できてしまう御時世ですが、昨日今日と半日くらい悩んでしまった locale の問題、ググってもマニュアルみても明確な説明が見つからなかったのでまとめてみました。en ロケールな人にはどうでも良い話題なのかもしれませんが。

Django 1.7(MacPorts で入れた Django が 1.7 だったので。そうでない人は普通 1.8 でしょうけど、とりあえず)の tutorial を見ながら勉強しているのですが、foo/models.py で定義した

class Bar(models.Model):
    a_date = models.DateField()

をテンプレートの

{{ bar.a_date }}

とか表示させても、

10月 29, 2003

みたいに中途半端なローカライズしかされません。マニュアルを読んでも、settings.py で USE_L10N が True になっていれば、自動的にローカライズされそうに見えるのですが、なんですか、この中途半端加減は。

テンプレートを

{{ bar.a_date|localize }}

とかしてもダメ。(bar.a_date|date:"Y/m/d" とかすれば処理されますけど、なんか違う。)

しばし考えます。そもそも、Django はブラウザの前にいる人がどんなロケールを期待しているのかを、どうやって知るのか?  たしかブラウザは HTTP のリクエストで Accept-Language: ja-jp とか送るはずですが、それを見ているのでしょうか。しかし、これも Django マニュアルの https://docs.djangoproject.com/en/1.7/topics/i18n/ を見て試しても、なんだかうまくいきません。みんなどうやっているんだーーー。

しばらくして、from django.utils.translation import activateactivate() というのを見つけました。foo/views.py で

from django.utils.translation import activate

def detail(request, id):
    activate('ja')
    bar = get_object_or_404(Foo, pk=id)
    return render(request, 'foo/detail.html', {'bar': bar})

とか書いてやると、ようやく

2003年10月29日

と表示されました。やったー!

しかしまだ心は晴れません。Accept-Language: ja-jp はどうなったんだ。ブラウザから指定してくれたロケールを参照したいじゃないか。さらに調べてみると、django.middleware.locale.LocaleMiddleware というものがあるそうです。なんかこれは非常に臭いです、直感的に。

試しに、settings.py の MIDDLEWARE_CLASSES に、このなんとか Middleware を追加し、先ほどの activate(‘ja’) を取り除いてみました。やった、ちゃんと日本語で日付が表示されたー。ちなみに、ブラウザの設定を変えて英語優先にしてみたら、

Oct. 29, 2003

となりました。フランス語にしたら、

29 octobre 2003

完璧です。

ようやくこれで気分すっきり、tutorial の続きを読み進めることができます。