トップ 差分 一覧 ping ソース 検索 ヘルプ PDF RSS ログイン

Google App Engine で Djangoを利用する



目次



記事一覧

キーワード

Google App Engine で Djangoを利用する

[Google App Engine][Django][Python]


 概要

  • Google App EngineWSGI 準拠のアプリケーションの実行をサポート
  • Django はこの規格をサポートしている
  • Google App Engine 上で実行する Django アプリケーションを構築(または既存のアプリケーションを移植)できる。

WSGI(Web Server Gateway Interface)

概要
  • Python には多様な Webアプリケーションフレームワークが存在
  • Web フレームワークの選択が使用できるWebサーバを制限したり、その逆の制限があったりする
  • WSGI はWebサーバとWebアプリケーションないしフレームワークとの間の簡潔で統一されたインタフェースを提示する
仕様の概要
  • WSGI のインターフェイスには二つの側面。
    • "サーバ"ないし"ゲートウェイ"側
    • "アプリケーション"ないし"フレームワーク"側

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

 Google App Engine 環境と Django 環境

2つの大きな違い

  1. Google App EngineSQL データベースを提供しないので、Django の標準のモデルクラスは使用できない
  2. 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のインストール

  • Windows 上で、Google が提供する SDK インストーラを使用している場合は、Python for Windows Extensions(Win32 向け拡張モジュール。 Python から COM を操作できるようになる) をイントールして、SDK を自動検出できるようにする必要がある

 ヘルパー

ダウンロード

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

解凍と配置

  • 上記サイトでは、"mysite という名前のディレクトリに展開" との記述があるが、これはDjangoのチュートリアルに習ったもので深い意味はない。
  • Eclipse PyDevを利用しているので、プロジェクトのディレクトリに配置し、起動する。

どうやら動いたようだ。WARNINGは現時点では気にしなくて良いとのこと。

WARNING で始まる行は無視して構いません。これは、データストアのデータを読めない、または PIL に問題があることを示しています。開発データストアにまだデータがなく、Python イメージングライブラリがコンピュータにインストールされていないことを警告しているだけです。

 起動してみる

ImportError: No module named _multiprocessing


Django 1.0 or greater is required!

  • エラー第2弾。どうもヘルパーはDjango 1.0 以降を要求しているようだ。
  1. http://code.google.com/p/googleappengine/downloads/list から、GoogleAppEngine_1.2.5.msi をダウンロードしてインストールしてみる・・・が、同梱されるDjangoは、0.96のようだ・・・
  2. Djangoのサイトから、Django-1.1.tar.gz.をダウンロードして、プロジェクトの直下に配置する。

TypeError: Initialization arguments are not supported

  • エラー第3弾。なかなか一筋縄ではいかない。。。
  • 構成は以下のような感じ。
    • appengine_django ・・・ appengine_helper_for_django-r86.zip
    • django ・・・ Django-1.0.3.tar.gz を展開したファイルからdjangoディレクトリ配下

 It worked #1

  • とりあえずローカル環境で動いている(?)ようだ。道のりは長い。

 zipimport

zipで圧縮して・・・

main.pyに以下を追加

# Add Django 1.0 archive to the path.
django_path = 'django.zip'
sys.path.insert(0, django_path)

 It worked #2


 サーバーに発行

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に修正

 It worked #3

よーーーやっとうごいた。

アプリケーションの作成

 ソースフォルダで、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 以下が作成される

 モデルの作成

ファイルの配置

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' )

 モデルの有効化


  • 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で自動的に提供される。

ビュー、テンプレートの作成〜実行

 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の編集

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 %}    

 動いた



YAGI Hiroto (piroto@a-net.email.ne.jp)
twitter http://twitter.com/pppiroto

Copyright© 矢木 浩人 All Rights Reserved.