Twitterもどきを作りながらGoogle App Engineの肝データストアを理解する

白石俊平
2008/04/14 17:00

今回はTwitter(もどき)を作りながらGoogle App Engineを利用する最大の目的ともいえる「データストア」について説明しよう。

リスト1:builder-example3.py

import os
import wsgiref.handlers

from google.appengine.api import users
from google.appengine.ext import db,webapp
from google.appengine.ext.webapp import template

class Message(db.Model):
    author = db.UserProperty()
    content = db.StringProperty()
    date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if self.request.get("myMessageOnly"):
            if not user:
                self.redirect(users.create_login_url(self.request.uri))
                return
            # GQLを用いた問い合わせ
            messages = db.GqlQuery("SELECT * FROM Message"
                                   " WHERE author = :author"
                                   " ORDER BY date DESC LIMIT 20", author=user)

        else:
            # Queryのメソッドを用いた問い合わせ
            messages = Message.all().order("-date").fetch(20)
        if not user:
             login_or_out = "Log in"
             url = users.create_login_url(self.request.uri)
        else:
            login_or_out = "Log out"
            url = users.create_logout_url(self.request.uri)
        path = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(
            template.render(path, {"messages": messages,
                                   "login_or_out": login_or_out,
                                   "url": url}))

class AddMessage(webapp.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if not user:
            loginUrl = users.create_login_url(self.request.uri)
            self.redirect(loginUrl)
            return
        else:
            content = self.request.get("content")
        # メッセージの保存
            message = Message(author=user,
                              content=content)
            message.put()
            self.redirect("/")

def main():
    application = webapp.WSGIApplication(
        [('/', MainPage),
         ('/add', AddMessage)],
        debug=True)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
    main()

リスト2:index.html (画面のテンプレート)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
  <a href="{{url}}">{{login_or_out}}</a>
  <form action="/add">
    メッセージ:<input name="content"><button>送信</button>
  </form><hr>
  <a href="/">すべてのメッセージ</a>
  <a href="/?myMessageOnly=1">あなたのメッセージのみ</a>
  <table>
    {% for message in messages %}
    <tr>
      <td>{{message.author}}曰く:</td>
      <td>「{{message.content|escape}}」 - {{message.date}}</td>
    </tr>
    {% endfor %}
  </table>
</body>
</html>

リスト3:app.yaml # アプリケーションの名称 application: builder-example3

# アプリケーションのバージョン
version: 1

# ランタイムの名称。現時点では「python」のみ
runtime: python

# アプリケーションが前提としているAPIのバージョン
api_version: 1

# URLと、その処理方法の定義
handlers:
- url: /.*
  script: builder-example3.py
記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 3日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ