銀月の符号

Python 使い見習いの日記・雑記

『Google App Engine プログラミング入門』第2章「チュートリアル」の誤記をまとめてみた

Google App Engineプログラミング入門』を通読した後、第2章「チュートリアル」のコードを実際に動かしてみようとしてみた。しかし動かない箇所が多数。 Python うろ覚えの人には発見が困難そうな誤りも。

でも誤記が多いというだけで放り投げらてしまうのはもったいないと思ったので、とりあえず動くものにするために修正すべき箇所を上げてみる。次の版では直りますように…。

誤植リスト

2月17日追記。 http://d.hatena.ne.jp/know94space/20100214 にて、さらに足りない部分をまとめてくださる方がいらっしゃいました。こちらもみてください。

p.40 2.3.2 テンプレートを使って表示してみる
from google.appengine.ext.webapp import template

import os も必要。

import os

from google.appengine.ext.webapp import template
p.42 2.4.2 モデルの宣言
class Bookmark(db.Model):
    title = db.StringProperty(require=True)
    url = db.LinkProperty(required=True)
    comment = db.TextProperty()

require ではなく required 。 url のほうはあっているのに…。

class Bookmark(db.Model):
    title = db.StringProperty(required=True)
    url = db.LinkProperty(required=True)
    comment = db.TextProperty()
p.45 2.6.1 新規登録画面を表示するRequestHandler の main
def main():
    application = webapp.WSGIApplication([
        ('/', ListBookmark), # 全ブックマークのブラウズ
        ('/add/', AddBookmark), # 新規登録画面
        ('/edit/(\d+)/', EditBookmark), # 編集画面
        ('/delete/(\d+)/', DeleteBookmark), # 削除画面
        ], debug=True)

まだ未定義のものについては、コメントアウトしておかないと、ためしに動かしてみた時に支障(NameError 例外)が出る。 EditBookmark, DeleteBookmark の定義が終わり次第、元に戻すこと。

def main():
    application = webapp.WSGIApplication([
        ('/', ListBookmark), # 全ブックマークのブラウズ
        ('/add/', AddBookmark), # 新規登録画面
        #('/edit/(\d+)/', EditBookmark), # 編集画面
        #('/delete/(\d+)/', DeleteBookmark), # 削除画面
        ], debug=True)
p.45 2.6.1 新規登録画面を表示するRequestHandler の AddBookmark
    def post(self, bookmark_id):
        """新規登録処理を行い、編集画面に遷移します。
        """
        url = self.request.POST['url']

post メソッドの仮引数 bookmark_id はあってはならない。

    def post(self):
        """新規登録処理を行い、編集画面に遷移します。
        """
        url = self.request.POST['url']
p.48 2.7 編集画面を作る
class EditBookmark(webapp.RequestHandler):
    def get(self, bookmark_id):
        """編集画面表示を行います。
        """
        bookmark = Bookmark.get_by_id(bookmark_id)
        data = {'bookmark': bookmark}
        path = os.path.join(os.path.dirname(__file__),
                'bookmark_edit.html')
        self.response.out.write(template.render(path, data))

    def post(self, bookmark_id):
        """更新処理を行い、一覧画面に遷移します。
        """
        bookmark = Bookmark.get_by_id(bookmark_id)
        bookmark.url = self.request.POST['url']
        bookmark.title = self.request.POST['title']
        bookmark.comment = self.request.POST['comment']
        bookmark.put()
        self.redirect("/")

bookmark_id は文字列なので、 get_by_id に渡す際、整数に直す必要がある。

class EditBookmark(webapp.RequestHandler):
    def get(self, bookmark_id):
        """編集画面表示を行います。
        """
        bookmark = Bookmark.get_by_id(int(bookmark_id))
        data = {'bookmark': bookmark}
        path = os.path.join(os.path.dirname(__file__),
                'bookmark_edit.html')
        self.response.out.write(template.render(path, data))

    def post(self, bookmark_id):
        """更新処理を行い、一覧画面に遷移します。
        """
        bookmark = Bookmark.get_by_id(int(bookmark_id))
        bookmark.url = self.request.POST['url']
        bookmark.title = self.request.POST['title']
        bookmark.comment = self.request.POST['comment']
        bookmark.put()
        self.redirect("/")
p.49 リスト2-6 bookmarks/bookmark_edit.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GAE Bookmark</title>
</head>
<body>
    <form name="form_edit" action="/edit/{{ bookmark.id }}" method="post">
        <dl>
            <dt>URL</dt>
            <dd>{{ error }}</dd>
            <dd><input type="text" name="title" size="50" value="{{ bookmark.title }}" /></dd>
            <dd><input type="text" name="url" size="50" value="{{ bookmark.url }}" /></dd>
            <dd><textarea name="comment">{{ bookmark.comment }}</textarea></dd>
        </dl>
        <input type="submit" value="更新" />
    </form>
    <form name="form_delete" action="/delete/{{ bookmark.id }}" method="post">
        <input type="submit" value="削除" />
    </form>
</body>
</html>

bookmark.id ではなく bookmark.key.id 。あと、末尾にスラッシュを加えること。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>GAE Bookmark</title>
</head>
<body>
    <form name="form_edit" action="/edit/{{ bookmark.key.id }}/" method="post">
        <dl>
            <dt>URL</dt>
            <dd>{{ error }}</dd>
            <dd><input type="text" name="title" size="50" value="{{ bookmark.title }}" /></dd>
            <dd><input type="text" name="url" size="50" value="{{ bookmark.url }}" /></dd>
            <dd><textarea name="comment">{{ bookmark.comment }}</textarea></dd>
        </dl>
        <input type="submit" value="更新" />
    </form>
    <form name="form_delete" action="/delete/{{ bookmark.key.id }}/" method="post">
        <input type="submit" value="削除" />
    </form>
</body>
</html>
p.50 2.8 データを削除する
class DeleteBookmark(webapp.RequestHandler):
    def post(self, bookmark_id):
        bookmark = Bookmark.get_by_id(bookmark_id)
        if bookmark:
            bookmark.delete()
        self.redirect("/")

「2.7 編集画面を作る」と同様。bookmark_id は文字列なので、 get_by_id に渡す際、整数に直す必要がある。

class DeleteBookmark(webapp.RequestHandler):
    def post(self, bookmark_id):
        bookmark = Bookmark.get_by_id(int(bookmark_id))
        if bookmark:
            bookmark.delete()
        self.redirect("/")