Google app engineでDjangoを動かす
April 09, 2008 at 10:36 AM | View Commentsまず、普通にGoogle app engineを使えるようにするには秋元さんのエントリーが詳しいのでそちらを参考に
- http://labs.cybozu.co.jp/blog/akky/archives/2008/04/google_app_engine_sdk.html
- http://labs.cybozu.co.jp/blog/akky/archives/2008/04/tried-google-app-engine.html
秋元さんはWindowsを使っているがMacの場合はdmgとpkgでインストールする。
ローカル環境であれこれするdev_appserver.pyと、デプロイするためのappcfg.pyはそれぞれ/user/local/bin/に入る
- /usr/local/bin/dev_appserver.py
- /usr/local/bin/appcfg.py
またdemoやlibなどのファイルたちは/usr/local/google_appengineにある。
Google app engineはPythonは2.5が必要なのでOS-X10.5以外の人は別途インストールしましょう。Djangoのインストールだがeveresさんの記事が分かりやすいです。
http://www.everes.net/2007/sep/06/install-django-for-begginers-osx/
アプリを作るディレクトリに移ります(どこでもいい)
% cd ~/tmp
/usr/local/google_appengine/libにあるdjangoを使ってプロジェクトを作る(今回はueblog33というアプリ名にしました)
% python /usr/local/google_appengine/lib/django/django/bin/django-admin.py startproject ueblog33
次のように4つのファイルができているはずです。
% ls ueblog33
__init__.py manage.py settings.py urls.py
アプリ直下にdjango自体が必要なのでコピーしましょう
% cp -r /usr/local/google_appengine/lib/django/django ueblog33/django
google app engineを使うためにはueblog33/main.pyを作る必要がある。
http://code.google.com/appengine/articles/django.html
のmain.pyをコピーしてしまいましょう。しかし、#Log errorの後の行はエラーになるので#でコメントアウトしておきましょう。
# Log errors
#django.dispatch.dispatcher.connect(
# log_exception,
# django.core.signals.got_request_exception)
次app.yamlをhttp://code.google.com/appengine/articles/django.html を参考につくる
application: ueblog33
version: 1
runtime: python
api_version: 1
handlers:
- url: /static
static_dir: static
- url: /.*
script: main.py
静的ファイルを作る場所を指定してあるようなのでstaticディレクトリを作っておきましょう
% mkdir ueblog33/static
次にアプリを作ります。今回はhogeという名前のアプリにします。
% cd ueblog33
% python manage.py startapp hoge
次にsettings.pyの設定。やはりhttp://code.google.com/appengine/articles/django.htmlの例でいいのですが
- ROOT_URLCONF = 'urls' にする
- INSTALLED_APPSに今さっきつくったアプリを入れる
ようにしましょう。
# Django settings for ueblog project.
import os
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
)
MANAGERS = ADMINS
LANGUAGE_CODE = 'ja'
SITE_ID = 1
USE_I18N = True
MEDIA_ROOT = ''
MEDIA_URL = ''
ADMIN_MEDIA_PREFIX = '/media/'
SECRET_KEY = '' #ここは自分のやつを使ってください
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
# 'django.template.loaders.eggs.load_template_source',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
#'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.doc.XViewMiddleware',
)
ROOT_URLCONF = 'urls'
ROOT_PATH = os.path.dirname(__file__)
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
ROOT_PATH + '/templates',
)
INSTALLED_APPS = (
#'django.contrib.auth',
'django.contrib.contenttypes',
#'django.contrib.sessions',
'django.contrib.sites',
'hoge',
)
次にueblog33/urls.pyの編集
今回は
http://ueblog33.appspot.com/hoge/list/
で一行掲示板を作りたいので以下の通り
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^hoge/list/$', 'hoge.views.bbs_list'),
)
次に/hoge/list/でアクセスされた場合の処理を任せるueblog/hoge/views.pyを作ります。
google app engineではdjango.modelを使えないのでgoogle.appenine.ext.dbを使ってます。また、googleのusersも使ってみました。
#!-*- coding:utf-8 -*-
from django.shortcuts import render_to_response
from django import newforms as forms
from google.appengine.ext import db
from google.appengine.api import users
import datetime
class Entry(db.Model):
created = db.DateTimeProperty()
body = db.StringProperty(required=True)
class EntryForm(forms.Form):
body = forms.CharField(max_length=100, min_length=1)
def bbs_list(request):
form = EntryForm(request.POST or None)
if form.is_valid():
e = Entry(body=unicode(request.POST["body"], 'utf8'), #unicodeで渡す必要がある
created=datetime.datetime.now())
e.put()
form = EntryForm()
query = Entry.all()
query.order('created')
user = users.get_current_user()
if user:
nickname = ("%s (<a href='%s'>sign out</a>)" % (user.nickname(), users.create_logout_url("/hoge/list/")))
else:
nickname = "名無しさん <a href='%s'>Sign in or register</a>." % users.create_login_url("/hoge/list/")
return render_to_response('hoge/entry_list.html', {'form':form, 'object_list':query, 'nickname':nickname})
最後の行でhoge/entry_list.htmlというテンプレートを使うようにしてるのでそれもつくります。
% mkdir hoge/templates
% mkdir hoge/templates/hoge
まず、ベースになるbase.htmlを ueblog33/hoge/template/base.html
に作ります。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
つぎに ueblog33/hoge/template/hoge/entry_list.htmlを作ります。
{% extends "base.html" %}
{% block title %}HOGE{% endblock %}
{% block content %}
<ul>
{% for object in object_list %}
<li>{{ object.body|escape }} : {{ object.created|date:"Y-m-d (D) H:i:s" }} : {{ nickname }}</li>
{% endfor %}
</ul>
<p>
<form method="POST" action="." >
{{ form }}
<input type="submit" />
</form>
</p>
{% endblock %}
次にローカル環境で動かす
最初のueblog33の親ディレクトリに移動して
% cd ..
% python /usr/local/bin/dev_appserver.py ueblog33
をするとhttp://localhost:8080/hoge/list/
で先ほどつくったアプリが動く。Ctrl + C で止まる(Windowsは止まらないのでタスクマネージャーから無理矢理止めた)
ちなみにローカルのdatastoreをクリアするには
% python dev_appserver.py --clear_datastore ueblog33/
とやる。
うまく動いているようなら
% python /usr/local/bin/appcfg.py update ueblog33
でデプロイできます。
django.modelが使えないのならdjango使う旨味はない気もしましたが、djangoはテンプレートとかよくできてるのでそれはそれでありな気がします。
試してから書きますけどThe Expando Classはかなり衝撃的な気がします。
http://code.google.com/appengine/docs/datastore/expandoclass.html
※ よくよく考えてみたらgoogle app engineに入ってるdjango 0.96じゃなくて最新版のでもいいのではないかと思ったらeveresさんがやっていた。
http://www.everes.net/2008/apr/09/django-on-google-app-engine/