Google App EngineでDjango 1.1を動かす

前回virtualenvを使って「GAE開発用」という名目でPython 2.5とDjango 0.96が動く仮想環境を作りました

が、調べてみたらいつの間にやらDjango 1.0と1.1がGAEでサポートされていたという事実を知りまして

ほかにもDjango 1.2を動かす方法なんかもWeb上では紹介されていたりして

なんだか楽しそう!というわけで、今回はDjango 1.1 on GAEを動かしてみたいと思います。

プロジェクトの準備

http://code.google.com/p/google-app-engine-django/からappengine_helper_for_django-r109.zipをダウンロードして解凍しましょう。これが、これから作るDjango on GAEプロジェクトになります。なので、解凍して中を見てみれば分かりますがDjango用のsettings.pyやmanage.pyやGAE用のmain.pyなどが入っています。プロジェクト名をつけましょう

$ mv appengine_helper_for_django mysite

次にプロジェクトに対してSDKがどこにあるのかシンボリックリンクを使って教えてあげる必要があります。(OSXの人には不要な操作らしいです)

$ cd mysite
$ ln -s /path/to/google_appengine .google_appengine

GAEではzipimportを使ってDjangoを読み込む

GAEに入っているのはDjango 0.96なのは変わりありません。なのでDjango 1.1を動かすには、ソースを時前で用意する必要があります。ところが、GAEでは1つのプロジェクトにつきファイルは3000個までという決まりがあり、Djangoは1600個を超えるファイル群からなる大きなものなのでかなり大きな容量を使ってしまうことになります。
そういった使う側の理由や、Google側としてもデータ量が多くなって嫌だという理由などで(おそらく)、zipに圧縮されたDjangoをzipimport使って読み込みます。こうすればファイルが1個になるしファイル自体の大きさも圧縮できます。
それと、2009年2月にリリースされたSDK 1.1.9からファイル1つあたりの最大の大きさが1MBから10MBに引き上げられました。もし、それ以前のものを利用している場合はSDKをアップデートしましょう。

django.zipを作る

というわけで、まずはDjango 1.1のzipファイルを作ります。手順は以下のよう

1. Django-1.1.2.tar.gzを解凍する(他のバージョンでも同様)
2. Django-1.1.2/django/ の中で必要なファイルをひとまとめにしてdjango.zipという名前にする

ドキュメントによっては昔の1MB制限をクリアするために、django/conf/localeが超巨大なので抜きましょう、とか書いてありますが、今はdjangoディレクトリ全体を入れても大丈夫みたいです。ですが、どうせGAEではDjangoのadminアプリケーションが動かないので、今回はadminとadmindocsディレクトリは排除することにしました。

$ wget http://www.djangoproject.com/download/1.1.2/tarball/
$ tar xzvf Django-1.1.2.tar.gz
$ cd Django-1.1.2
$ zip -r ~/django.zip django -x ‘django/contrib/admin*’

そして、このdjango.zipをmysiteに追加します

$ mv ~/django.zip mysite

これでhelperさんが勝手にdjango.zipを読み込んでくれます。

virtualenvを使いたかったが...

さぁこれで起動できるぞ!と思ったのですが、どうやらappengineとvirtualenvは相性が悪いらしく、virtualenv上のpython2.5で起動すると

ImportError: No module named unittest

といわれてダメでした。sys.pathを見てもきちんと設定されているし、何がなんだかよく分からなかったので、今回は普通のpython2.5を使って開発をしていきます。解決法が分かる人いたら教えて下さい。><

Django開発サーバを起動する

通常のGAEではdev_appserver.pyを使って起動しますが、helperを使っているなら通常のdjangoと同じ感覚で開発サーバを起動します

$ python2.5 manage.py runserver
WARNING:root:Could not read datastore data from /tmp/django_google-app-engine-django.datastore
WARNING:root:Could not initialize images API; you are likely missing the Python "PIL" module. ImportError: No module named _imaging
INFO:root:zipimporter('/home/yuku_t/workspace/mysite/django.zip', 'django/core/serializers/')
INFO:google.appengine.tools.appengine_rpc:Server: appengine.google.com
WARNING:root:Could not read datastore data from /tmp/django_google-app-engine-django.datastore
WARNING:root:Could not initialize images API; you are likely missing the Python "PIL" module. ImportError: No module named _imaging
INFO:root:Running application google-app-engine-django on port 8000: http://localhost:8000

この時、datastoreが読めないとかPILがインポートできない、などのWARNINGが出ても気にする必要はありません。
これでhttp://localhost:8000にアクセスしたら無事にIt worked!を見ることができました。