トップ 一覧 ping 検索 ヘルプ RSS ログイン

Google App Engine で Djangoを利用するの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!Google App Engine で Djangoを利用する
[Google App Engine][Django][Python]

*http://code.google.com/intl/ja/appengine/articles/appengine_helper_for_django.html
*http://code.google.com/p/google-app-engine-django/

!!概要
*Google App Engine は [WSGI|http://www.google.co.jp/custom?hl=ja&client=pub-4280062068315072&cof=FORID%3A1%3BGL%3A1%3BLBGC%3A336699%3BLC%3A%230000ff%3BVLC%3A%23663399%3BGFNT%3A%230000ff%3BGIMP%3A%230000ff%3BDIV%3A%23336699%3B&domains=typea.info%3Btypea.dip.jp&q=WSGI&btnG=%E6%A4%9C%E7%B4%A2&sitesearch=] 準拠のアプリケーションの実行をサポート
*Django はこの規格をサポートしている
*Google App Engine 上で実行する Django アプリケーションを構築(または既存のアプリケーションを移植)できる。
!WSGI(Web Server Gateway Interface)
*http://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface
::概要
*Python には多様な Webアプリケーションフレームワークが存在
*Web フレームワークの選択が使用できるWebサーバを制限したり、その逆の制限があったりする
*WSGI はWebサーバとWebアプリケーションないしフレームワークとの間の簡潔で統一されたインタフェースを提示する
::仕様の概要
*WSGI のインターフェイスには二つの側面。
**"サーバ"ないし"ゲートウェイ"側
**"アプリケーション"ないし"フレームワーク"側

*アプリケーション側によって提供される呼び出し可能なオブジェクト(通常は関数やメソッド)を呼び出す。
*ミドルウェア の考え方を提供する。
*WSGI サーバーと WSGI アプリケーションの "中間に"挿入できるよう、WSGIミドルウェアは両方の側の API を実装。
*ミドルウェアはサーバーの観点からはアプリケーションとして動作し、アプリケーションの観点からはサーバーとして動作する。

!!Google App Engine 環境と Django 環境
!2つの大きな違い
+Google App Engine は SQL データベースを提供しないので、Django の標準のモデルクラスは使用できない
+Django が試みる特定のモジュールのインポートとアクション(テスト データベースの作成と削除など)が、Google App Engine では制限されている
""Google では、こうした違いのほとんどを配慮する必要がなくなるよう、ヘルパーを作成し、Google App Engine では機能しない Django の動作に対して、別の実装を提供

!!!以下実際の手順
基本的に、http://code.google.com/intl/ja/appengine/articles/appengine_helper_for_django.html を参考にするも、いろいろはまりポイントあり。

!![Python for Windows Extensions|http://sourceforge.net/projects/pywin32/]のインストール
*Windows 上で、Google が提供する SDK インストーラを使用している場合は、[Python for Windows Extensions|http://sourceforge.net/projects/pywin32/](Win32 向け拡張モジュール。 Python から COM を操作できるようになる) をイントールして、SDK を自動検出できるようにする必要がある
{{ref_image gae_django02.jpg}}

!!ヘルパー
!ダウンロード
*http://code.google.com/p/google-app-engine-django から、appengine_helper_for_django-r86.zip をダウンロードした。
*ただ、CurrentDownloadにエントリがなく、上記ファイルはDeprecatedとなってしまっている。。。

!解凍と配置
*[上記サイト|http://code.google.com/intl/ja/appengine/articles]では、"mysite という名前のディレクトリに展開" との記述があるが、これは[Djangoのチュートリアル|http://docs.djangoproject.com/en/dev/intro/tutorial01/?from=olddocs]に習ったもので深い意味はない。
*Eclipse PyDevを利用しているので、プロジェクトのディレクトリに配置し、起動する。
{{ref_image gae_django03.jpg}}
どうやら動いたようだ。WARNINGは現時点では気にしなくて良いとのこと。
""WARNING で始まる行は無視して構いません。これは、データストアのデータを読めない、または PIL に問題があることを示しています。開発データストアにまだデータがなく、Python イメージングライブラリがコンピュータにインストールされていないことを警告しているだけです。

!!起動してみる
!ImportError: No module named _multiprocessing
*エラー第1弾。以下を参考に対処してみる。
*http://d.hatena.ne.jp/tmatsuu/20090818/1250606215
{{ref_image gae_django04.jpg}}

!Django 1.0 or greater is required!
*エラー第2弾。どうもヘルパーはDjango 1.0 以降を要求しているようだ。
{{ref_image gae_django05.jpg}}
+http://code.google.com/p/googleappengine/downloads/list から、GoogleAppEngine_1.2.5.msi をダウンロードしてインストールしてみる・・・が、同梱されるDjangoは、0.96のようだ・・・
+[Djangoのサイト|http://www.djangoproject.com/download/]から、Django-1.1.tar.gz.をダウンロードして、プロジェクトの直下に配置する。

!TypeError: Initialization arguments are not supported
*エラー第3弾。なかなか一筋縄ではいかない。。。
{{ref_image gae_django06.jpg}}
*http://code.djangoproject.com/ticket/10727 を見ると、どうもDjangoのバージョンが新しくてもだめなようだ。もう一度、一つ前のリリース Django-1.0.3.tar.gz をダウンロードして、配置する。
{{ref_image gae_django07.jpg}}
*構成は以下のような感じ。
**appengine_django ・・・ appengine_helper_for_django-r86.zip
**django ・・・ Django-1.0.3.tar.gz を展開したファイルからdjangoディレクトリ配下
{{ref_image gae_django08.jpg}}
!!It worked #1
*とりあえずローカル環境で動いている(?)ようだ。道のりは長い。
{{ref_image gae_django09.jpg}}

!!zipimport
*プロジェクト配下にDjangoを置いたが、GAEでは、ファイル数に上限(1000)があり、このままでは発行できない。
*djangoディレクトリをアーカイブして、そこからロードするzipimportという機能が利用できる。
*http://code.google.com/intl/ja/appengine/articles/django10_zipimport.html
!zipで圧縮して・・・
{{ref_image gae_django11.jpg}}
!main.pyに以下を追加
 # Add Django 1.0 archive to the path.
 django_path = 'django.zip'
 sys.path.insert(0, django_path)
!!It worked #2
{{ref_image gae_django12.jpg}}

!!サーバーに発行
 C:\Program Files\Google\google_appengine>appcfg.py update "C:\Program Files\eclipse3.4R2\workspace\typea-services\src"
 C:\Program Files\Google\google_appengine\appcfg.py:41: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  os.path.join(DIR_PATH, 'lib', 'antlr3'),
 Scanning files on local disk.
 Initiating update.
 Error 403: --- begin server output ---
 You do not have permission to modify this app (app_id=u'google-app-engine-django').
 --- end server output ---
*上記エラー。ヘルパーのアプリケーションIDのままになっていたので、自分のIDに修正
{{ref_image gae_django13.jpg}}
!!It worked #3
よーーーやっとうごいた。
{{ref_image gae_django14.jpg}}
!!!アプリケーションの作成
!!ソースフォルダで、python manage.py startapp を実行
::実行コマンド
 python manage.py startapp [app_name]
::実行例
 C:\Program Files\eclipse3.4R2\workspace\typea-services\src>python manage.py startapp gaetest
 C:\Program Files\Google\google_appengine\google\appengine\api\datastore_file_stub.py:40: 
 DeprecationWarning: the md5 module is deprecated; use hashlib instead
   import md5
 C:\Program Files\Google\google_appengine\google\appengine\api\memcache\__init__.py:31: 
 DeprecationWarning: the sha module is deprecated; use the hashlib module
 instead
   import sha
 WARNING:root:Could not read datastore data from 
 c:\docume~1\admini~1\locals~1\temp\django_typea-services.datastore
 WARNING:root:Could not read datastore data from 
 c:\docume~1\admini~1\locals~1\temp\django_typea-services.datastore.history
 WARNING:root:Could not initialize images API; 
 you are likely missing the Python"PIL" module. ImportError: No module named _imaging
 INFO:root:zipimporter('C:\\Program Files\\eclipse3.4R2\\workspace\\typea-services\\src\\django.zip', 
 'django\\core\\serializers\\')

*geatest 以下が作成される
{{ref_image gae_django15.jpg}}
!!モデルの作成
*[Djangoチュートリアルでのモデル作成|/tips/wiki.cgi?page=Django+%BA%C7%BD%E9%A4%CE%A5%A2%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3+1#p12]
!ファイルの配置
{{ref_image gae_django17.jpg}}
!models.pyの編集
*モデルを作成するには、ヘルパーが提供するモデル クラスと、Google App Engine のデータストアプロパティを使用する必要がある。
*Django標準のモデル クラスとプロパティ クラスは機能しない。
*モデルでは Djangoモデルクラスは使用されないが、ヘルパーによって Djangoモデルと同様に取り扱うことができ、モデルは Djangoに登録される。

 from appengine_django.models import BaseModel
 from google.appengine.ext import db 
 
 # Create your models here.
 class GaeTest(BaseModel):
     message = db.StringListProperty()
     create_date = db.DateTimeProperty('data created')

!!APIをShellから使用する

!python manage.py shell コマンドを実行
::実行例 (モデルを保存してみる)
 C:\Program Files\eclipse3.4R2\workspace\typea-services\src>python manage.py shell
             :
 Type "help", "copyright", "credits" or "license" for more information.
 (InteractiveConsole)
 >>> from gaetest.models import GaeTest
 >>> import datetime
 >>> g = GaeTest(message='first gae model.',create_date=datetime.datetime.now())
 >>> g.save()
 datastore_types.Key.from_path(u'GaeTest', 1, _app_id_namespace=u'typea-services' )

!!モデルの有効化
*[Djangoチュートリアルでのモデルの開始|/tips/wiki.cgi?page=Django+%BA%C7%BD%E9%A4%CE%A5%A2%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3+1#p15]
*Google App Engine を使用するときは、モデルのデータベース テーブルを明示的に作成する必要はない。
*そのため sql*、syncdb、validate のコマンドは不要。ヘルパーはこれらのコマンドを使用しないように、manage.py から削除する。
*モデルを有効化するために必要なことは、settings.py を編集し、[INSTALLED_APPS に追加する|/tips/wiki.cgi?page=Django+%BA%C7%BD%E9%A4%CE%A5%A2%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3+1#p11]だけ。

*settings.py
 INSTALLED_APPS = (
      'appengine_django',
 #    'django.contrib.auth',
 #    'django.contrib.contenttypes',
 #    'django.contrib.sessions',
 #    'django.contrib.sites',
      'gaetest',  # この行を追加
 )

!!管理サイト
*Django 管理サイトは SQL データベースのコンセプトと密接に関係しているため、Google App Engine ではサポートされていない。
*開発用 appserver により、代わりの管理インターフェースが、/_ah/adminで自動的に提供される。

*http://localhost:8080/_ah/admin/datastore
{{ref_image gae_django16.jpg}}
!!!ビュー、テンプレートの作成〜実行
*[Djangoチュートリアル|/tips/wiki.cgi?page=Django+%BA%C7%BD%E9%A4%CE%A5%A2%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3+3#p7]
*動作確認のため、簡単に実装
!!urls.pyの編集
::settings.pyファイルのROOT_URLCONF 設定 にて、URLマッピングファイルを指定
 ROOT_URLCONF = 'urls'

::urls.pyに以下の行を追加
*タプルに、正規表現、ハンドラを記述する
*正規表現にマッチするリクエストがハンドラによって処理される
 urlpatterns = patterns('',
     (r'^gaetest/$',     'gaetest.views.index'),  # 初期表示
     (r'^gaetest/add/$', 'gaetest.views.add'),    # データ追加
 )

!!views.pyの編集
*ハンドラの実装
*上記、urls.py の正規表現に一致するリクエストがここで処理される
*[GAEのデータストアAPI|http://code.google.com/intl/ja/appengine/docs/python/gettingstarted/usingdatastore.html]を利用してデータを登録、検索
 from django.shortcuts import render_to_response
 from gaetest.models import GaeTest
 import datetime
 
 def index(request):
     g_list = GaeTest.gql('order by message')
     return render_to_response('gaetest/index.html', {'g_list':g_list})
     
 def add(request):
     msg = request.POST['message']
     g = GaeTest(message=msg, create_date=datetime.datetime.now())
     g.save()
     g_list = GaeTest.gql('order by message')
     return render_to_response('gaetest/index.html', {'g_list':g_list})

!!index.html の編集
*テンプレートの作成
*上記views.pyで処理され、結果がコンテキストに与えられているので、それに基づいて画面を生成
 <form action="/gaetest/add/" method="post">
     message:<input type="text" name="message"/>
     <input type="submit" value="add"/>
 </form>
 {% if g_list %}
     <ul>
     {% for g in g_list %}
         <li>{{ g.message }}</li>
     {% endfor %}
     </ul>
 {% else %}
     <p>No GaeTest are available.</p>
 {% endif %}    
!!動いた
{{ref_image gae_django18.jpg}}