GoogleAppEngineでDjangoのバージョン上げたらUnicodeEncodeError発生した

Google App Engine では、Django: 1.2, 1.1, 1.0, 0.96が使える。で、SDKには、Django 1.2と 0.96 が含まれていて、SDKでは通常0.96が使われています。

(参考)Third-party Python Libraries in Python 2.5 – Google App Engine — Google Developers
The App Engine Python environment includes these versions of Django: 1.2, 1.1, 1.0, and 0.96. Django 1.2 and 0.96 are included with the App Engine SDK. Legacy Django version 0.96 is currently imported by default when an app imports the django package.

この状態で、GoogleAppEngineの本番環境にアプリをUploadして動かしていると、ログにこんなWarningメッセージが出ていた。

You are using the default Django version (0.96). The default Django version will change in an App Engine release in the near future. Please call use_library() to explicitly select a Django version. For more information see

近いうちにバージョン上がりますって話。
というわけで、自分の環境で使っているDjangoバージョンを1.2に上げたら、テンプレートの描画の処理のところでUnicodeEncodeErrorが出て、ブラウザからWeb画面がまったく見れなくなった。。

エンコード変換の記述をなおしたら、正常に戻ったんだけど、
実はこのUnicodeEncodeErrorについては、Django 0.96の時にも発生したことがあって、その時にOKだった対処がダメになって、ちょっとなやまされた。

僕が使っている環境
Windows7(64Bit)
Python 2.5.4
Google App Engine SDK for Python 1.7.1
Aptana Studio 3.2.2


(1)はじめに

Pythonで日本語を取り扱う場合はUnicode文字列をつかうことになります。
文字コードUTF-8を使っているときは、uをつけて
print u‘Helloと表示’

とか書きます。

GoogleAppEngineで、とりあえずPrint文みたいなことをする場合、self.response.out.write()を使いますが、そこでもuをつければOKです。
self.response.out.write(u‘パラメータは=%s<br>\n’ % param)

といった感じ。

今回僕がハマったのは、
self.response.out.write(template.render(path, template_values))

のところ。Django テンプレートを使用してHTMLを描画する部分です。

エラー内容はこんな感じ。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 69-79: ordinal not in range(128)

これのやっかいなところは、自分のPC上(Google App Engine SDK)では、エラーが起きないってこと。
Webの本番環境でのみ発生する。


(2)Django 0.96での対処

テンプレートで使用している変数の中身が、ユニコードで格納されていないのか? って思ってハマったんだけど、結局、template.renderのところに、decodeをつけたら正しく動いた。

self.response.out.write(template.render(path, template_values).decode('utf-8'))

なぜencode(‘utf-8’)じゃないんだろう? という素朴な疑問がわいたけど、とりあえずそれ以上悩むのはやめた。


(3)Django 1.2での対処

Djangoのバージョン変更のやり方は、先に記載したページに載っている。

(参考)Third-party Python Libraries in Python 2.5 – Google App Engine — Google Developers

「アプリのソースコードに文言を記載して、そのモジュールのみに対応させるやり方」と、
「ファイルに設定してアプリ全体に適用させるやり方」がある模様。
とりあえず僕は、アプリ全体に適用することした。

やり方は、
アプリケーションのルート ディレクトリ(app.yaml とおなじ場所)に、appengine_config.py というファイルを作成し、以下の内容を記述する。

webapp_django_version = '1.2'

その後、アプリを動かすと、UnicodeEncodeErrorが起きた。今回もまた、
自分のPC上(Google App Engine SDK)では、エラーが起きない、Webの本番環境でのみ発生する。

悩まされてた結果、decodeをやめてencodeにしたら動いた。というかエンコード処理を書かなくても動く。

self.response.out.write(template.render(path, template_values))
もしくは
self.response.out.write(template.render(path, template_values).encode('utf-8'))

どちらでもOK

なにこれ。バグが治ったってこと?

チュートリアルを見ても、このあたりの記述が見つけれられなかったので、
とりあえず僕は、encodeの記述なしで行くことにした。
template.render(path, template_values).encode(‘utf-8’)

僕は、Python 2.5.*を使っているので、こちらも早めにPython 2.7に上げておいたほうがよさそう。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s