GAEpでiPhone向けWebアプリを作る (7)リクエストハンドラをを実装していく
前回の続きです。
リクエストハンドラを実装していく
続いて、GAEp のリクエストハンドラを実装していきます。
各実装ごとに部分的に書いていきます。
MainView の実装
MainView#get() では、単純に html を出力します。
todo/handlers.py内
import os from google.appengine.ext.webapp import template # 中略 # class MainView(webapp.RequestHandler): # def get(self): s_tplpath = 'templates/views.tpl' path = os.path.join(os.path.dirname(__file__), s_tplpath) self.response.out.write(template.render(path, {}))
- templates/views.tpl という名称のテンプレートファイルを http レスポンスとして出力しています。
- テンプレートファイルと言いつつ、実はテンプレートではなく、html ファイルそのものです。データを埋め込みません。render() メソッドの第2引数は空オブジェクトです。
- templates/views.tpl は、staticdir/views.html のシンボリックリンクになっています。
- staticdir/views.html には、すべてのビューが含まれています。これは次回以降に。
GAEp のテンプレートエンジンは、デフォルトでは django のテンプレートエンジンとなっています。django のテンプレートエンジンのリファレンスは以下。
サーバサイドのテンプレートエンジンを利用したビューとモデルのバインディングはそれはそれでパワフルですが、今回はバインディングはクライアントサイドの javascript で行います。なので、ここで返すのは静的ファイルのみです。
ToDoList の実装
続いて、ToDoList#get() の実装です。
todo/handlers.py内
import logging from google.appengine.ext import webapp from google.appengine.api import users from django.utils import simplejson as json from todo.models import ToDoItem # 〜〜〜 # class ToDoList(webapp.RequestHandler): # def get(self): logging.debug('ToDoList#get') data = None user = users.get_current_user() if user: userinfo = { 'nickname': user.nickname(), 'logout_url': users.create_logout_url('/todo/bye.html') } q = ToDoItem.all() q.filter('owner =', user) q.order('deadline') results = q.fetch(20) itemlist = [{ 'key':str(item.key()), 'title':item.title, 'detail':item.detail, 'deadline':item.deadline.strftime('%Y-%m-%d'), } for item in results] data = { 'userinfo': userinfo, 'items': itemlist, } self.response.content_type = 'application/json' json.dump(data, self.response.out, ensure_ascii=False) return
import 文は、この部分に必要なものだけ書いています。
処理の流れは以下です。
- アクセスしている人がログイン済み(user != None)だったら、
- そのユーザの20件の ToDo アイテムを古いものから検索し、レスポンス用オブジェクト(itemlist)に変換し、
- ToDo アイテム(itemlist)とユーザ情報(userinfo)をひとまとめ(data)にして
- JSON データとして http レスポンスに出力
アクセスしている人がログイン済みのユーザかどうかは、User クラスのインスタンスを取得することで確認できます。
user = users.get_current_user() if user: userinfo = { 'nickname': user.nickname(), 'logout_url': users.create_logout_url('/todo/bye.html') }
取得は、google.appengine.api.users パッケージの get_current_user() 関数で行います。
リファレンスは以下です。
user != None ならログイン済み、そうでなければログインしていません。
また、ログアウト URL は、同じパッケージの create_logout_url() 関数で作成できます。この URL にアクセスすることで、ユーザはログアウトできます。引数には、ログアウト後のリダイレクト先 URL を指定できます。
以下の部分で、ユーザの ToDo アイテムを締め切りの古いものから20件検索しています。
q = ToDoItem.all() q.filter('owner =', user) q.order('deadline') results = q.fetch(20)
で、検索結果をレスポンス用オブジェクト(itemlist)に変換しています。
itemlist = [{ 'key':str(item.key()), 'title':item.title, 'detail':item.detail, 'deadline':item.deadline.strftime('%Y-%m-%d'), } for item in results]
itemlist はディクショナリオブジェクトのリストです。ひとつの ToDo アイテムは、ひとつのディクショナリオブジェクトで表し、以下を持っています。
- key
- ToDo アイテムのキー。これには、ToDoItem エンティティのキーをそのまま利用する。
- title
- ToDoItem エンティティの title プロパティ(ToDo タイトル)の値
- detail
- ToDoItem エンティティの detail プロパティ(ToDo 内容詳細)の値
- deadline
- ToDoItem エンティティの deadline プロパティ(この ToDo の締め切り)の値。"2011-06-05" のように"年-月-日" という書式で。
で、最後に、ユーザ情報(userinfo)と ToDo アイテムのレスポンス用オブジェクト(itemlist)をひとつのオブジェクト(data)にまとめ、JSON 形式で http レスポンスに書き出しています。
data = { 'userinfo': userinfo, 'items': itemlist, } self.response.content_type = 'application/json' json.dump(data, self.response.out, ensure_ascii=False)
GAEp には simplejson が入っているので、それを利用しています。ちょー簡単です。
長くなったので今回はここまで。
参考
Google App Engine については、基本的に Google が公開しているデベロッパーガイドを見ればだいたいのことはわかります。内容もわかりやすいです。
- http://code.google.com/intl/ja/appengine/docs/python/gettingstarted/
- http://code.google.com/intl/ja/appengine/docs/python/overview.html
基本的にはこれらのサイトを見ればほとんどのことはわかりますが、その他に僕は以下の本を参考にしています。
- 作者: Dan Sanderson
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2009/11/15
- メディア: ペーパーバック
- クリック: 29回
- この商品を含むブログ (6件) を見る
和訳も出ているようです。
- 作者: Dan Sanderson,玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/01/24
- メディア: 大型本
- 購入: 5人 クリック: 414回
- この商品を含むブログ (27件) を見る