最近の更新履歴

このドキュメントについて

現在、このドキュメントは翻訳中です。翻訳は「伊藤 哲之輔」が2008/1 に開始しました。リンクのテキストに英語を含むものについては、リンク先はまだ英語版であることを意味しています。

誤訳等の指摘についてはhttp://tetsunosukelab.appspot.com/contact へお寄せください。

2009/3 共同執筆にTakayo Hamasaki氏を迎えました。今後とも充実させていこうと思います。

最新情報

  • 誤訳指摘用メールフォームを作成しました。
  • 日本版用のコンテンツを作成していこうと思います
  • チュートリアルの和訳完了
その後はクラスリファレンスの和訳を予定しています。クラスリファレンスそのものが全てそろっていないのでどうしたものか・・・とは思いますが。

なお、公式ドキュメントにてToDoアプリケーションの記事が開始されたようです。追って和訳します。

GAEOを使ってシンプルなブログを作成する

このページではGAEOを用いてblogを作る方法を説明します。
NOTE: GAEOのバージョンは最低でもrevision #68 でなくてはいけません
  1. ブログプロジェクトの作成.

    作業ディレクトリにて、gaeo.py スクリプトでプロジェクトを作成します.


     すると、スクリプトにより、blog ディレクトリと基本的なファイルが作成されます。

  2. モデルの作成

    blogの投稿やコメントをAppEngineのデータストアに格納するには、postとcommentのモデルを定義する必要があり

    ます。モデルは
    gaeogen.py スクリプトにより作成します。
    モデルとScaffold の違いは、Scaffoldはモデルだけでなくコントローラとテンプレートも作成することです。

    モデルを作成すると、モデルにフィールドができていることがわかります。

     application/model/post.py
    from google.appengine.ext import db
    from gaeo.model import BaseModel

    class Post(BaseModel):
        content = db.TextProperty(required=True)
        post_at = db.DateTimeProperty(required=True, auto_now_add=True)
        title = db.StringProperty(required=True)

    Post モデルはblog の記事を保存するのに利用します。title (タイトル), content(内容), post_at(投
    稿時刻)のフィールドを用意します。


     application/model/comment.py
    from google.appengine.ext import db
    from gaeo.model import BaseModel

    from model.post import Post

    class Comment(BaseModel):
        author = db.StringProperty(required=True)
        content = db.TextProperty(required=True)
        posted_at = db.DateTimeProperty(required=True, auto_now_add=True)
        
    Comment.belongs_to(Post)

    PostとCommentの間には、1対nのリレーションを作成するために BaseModelのクラスメソッド、belongs_toを利用します。このメソッドを呼ぶと、comment エンティティはその post フィールドを使うことでpost モデルにアクセスでき、post エンティティは、comments フィールドを用いてコメントにモデルにアクセスできます。
  3. post コントローラの作成

    次に記事を書いて保存する、ページと controller を作成しましょう。

    Scaffold は post コントローラ と 4つのテンプレート(new, show, index 、と create)を作成してくれますnew テンプレートは新規記事の投稿を行うのに使います。new テンプレートを下記のように編集してください。
     application/templates/post/new.html
    <form method="post" action="/post/create">
      <fieldset>
        <legend>Post a new article</legend>
        <p>
          <label for="title">Title: </label><br/>
          <input type="text" name="title" id="title" size="20" tabindex="1" />
        </p>
        <p>
          <label for="content">Content: </label><br/>
          <textarea id="content" name="content" rows="5" cols="40"></textarea>
        </p>
        <p>
          <input type="submit" value="Post"/>
        </p>
      </fieldset>
    </form>

    http://localhost:8080/post/new でこのページを見ることができます


    しかし/post/create アクションを実装していないため、まだ記事を作ることはできません。 post コントローラにcreate メソッドを定義しましょう。
    application/controller/post.py
    from gaeo.controller import BaseController

    from model.post import Post

    class PostController(BaseController):
        def new(self):
            pass

        def show(self):
            pass

        def create(self):
            Post(title=self.params['title'],
                 content=self.params['content']).put()
            self.redirect('/')

    'Post' ボタンを押すと、フォームによりデータが /post/create アクションに送られ、ディクショナリ
    self.params に保存されます。put メソッドによりデータが保存された後、self.redirect('/') の実行により、
    ルートパスにリダイレクトします。
  4. 全ての記事を表示する

    投稿された記事はデータストアに保存されています。この記事をルートパス(/)にて全て表示しましょう。
    welcome コントローラを修正します。

    application/controller/welcome.py
    from gaeo.controller import BaseController
    from model.post import Post

    class WelcomeController(BaseController):
        def index(self):
            p = Post.all()
            p.order('-post_at')
            self.posts = p.fetch(10)

    データストア APIの fetch() メソッドを使います。10 件の投稿を取得し、
    メンバ変数 self.posts に格納します。それから order() メソッドにより、
    投稿をpost_at フィールドの降順でソートします。
    投稿のタイトルを表示するためにwelcome/index テンプレートを修正しましょう。

    application/templates/welcome/index.html
    {% if posts %}
        {% for post in posts %}
        <div>{{ post.post_at }}</div>
        <h1><a href="/post/show/{{ post.key }}">{{ post.title }}</a></h1>
        <hr/>
        {% endfor %}
    {% else %}
        <h1>No Posts</h1>
    {% endif %}

    <a href="/post/new">Post an new article</a>

    self.posts に投稿を保存しているので、値がGAEO によりテンプレートレンダリングエンジンに渡されます。  
    これにより postss 変数を welcome/index テンプレートで利用できます。投稿のタイトルと、投稿内容を表示する
    ためのリンクを表示しました。 index ページは下記のようになるでしょう
    :


    投稿の内容を表示する方法は次のステップをご覧ください。

  5. 記事を(一件)表示する

    ステップ4では、/post/show/<key> へのリンクを個別の記事を表示するために用意しました。 これにより GAEO はパラメータ id  ( main.py/:controller/:action/:id がデフォルトルートになっています).   で show アクションを PostController 内で呼び出します。show メソッドをPostController から呼び出すことで特定の記事を取得することが出来ます。

    application/controller/post.py
    from model.post import Post
    ...
        def show(self):
            self.post = Post.get(self.params['id'])
    ...

    モデルの get メソッドにより。キー に応じて値を取得することができます。 今回はパラメーター id をキーとしてデータをリクエストしているので、特定の post を get メソッドにて処理します。また、post データを self.post メンバ変数に保存しておきます。

    記事を表示するために post/show テンプレートを編集します

    application/templates/post/show.html
    {% if post %}
      <h1 class="title">{{ post.title }}</h1>
      <hr/>
      <div class="content">
        {{ post.content }}
      </div>
      <hr/>
      <div class="meta">
        Post at {{ post.post_at|date }}
      </div>
    {% else %}
      <h1>Article Not Found</h1>
    {% endif %}
    <a href="/">&laquo; Back</a>

    これで記事へのリンクをクリックすると、内容が表示されるようになりました。


    これでシンプルなブログのできあがりです。

  6. コメントを追加する

    コメントのフィールドをまだ追加していません。訪問者からの声を聞くために、コメントが残せるようにフォームを作成しましょう。コメントフォームを追加するのは難しくありません。 post/show テンプレートを修正しましょう。

    application/templates/post/show.html
    {% if post %}
      <h1 class="title">{{ post.title }}</h1>
      <hr/>
      <div class="content">
        {{ post.content }}
      </div>
      <hr/>
      <div class="meta">
        Post at {{ post.post_at|date }}
      </div>
      <hr/>
      <form method="post" action="/comment/post">
        <input type="hidden" name="post_key" value="{{ post.key }}"/>
        <p><label>Name:</label> <input type="text" name="author"/></p>
        <p><label>Comment:</label><br/><textarea name="comment"></textarea></p>
        <p><input type="submit" value="Leave comment"/></p>
      </form>
      <hr/>
    {% else %}
      <h1>Article Not Found</h1>
    {% endif %}
    <a href="/">&laquo; Back</a>

    赤でハイライトされた部分がコメントフォームです。記事のキーをhiddenで送信しています。また、二つのフィールド、名前、コメントを訪問者のために用意しています。submit ボタン(コメントを残す)を押したときに、フォームのデータは CommentController に送られます。(まだ作られていません) gaeogen.py コマンドでコントローラを作成しましょう:


    comment.pyに少しコードを追加します

    application/controller/comment.py
    from gaeo.controller import BaseController

    from model.post import Post
    from model.comment import Comment

    class CommentController(BaseController):
        def post(self):
            p = Post.get(self.params['post_key'])
            c = Comment(post=p,
                        author=self.params['author'],
                        content=self.params['comment'])
            c.put()
            self.redirect('/post/show/%s' % self.params['post_key'])

    既に belongs_to(Post) の関係をcommentモデルに定義してあるのでreference property が post モデルに存在します。post 属性をインスタンス作成時に設定することに酔って、commentをpostと関連づけしています。commentを保存した後、post に戻ります。

    しかし  post/show テンプレートはまだコメントを表示しません。そこでテンプレートに少しコードを追加する必要があります。:

    application/templates/post/show.html
    {% if post %}
      <h1 class="title">{{ post.title }}</h1>
      <hr/>
      <div class="content">
        {{ post.content }}
      </div>
      <hr/>
      <div class="meta">
        Post at {{ post.post_at|date }}
      </div>
      <hr/>
      <h3>Comments</h3>
      {% if post.comments %}
      <ul>
          {% for c in post.comments %}
          <li>{{ c.author }} say "{{ c.content }}"</li>
          {% endfor %}
      </ul>
      {% endif %}
      <hr/>
      <h3>Leave a comment</h3>
      <form method="post" action="/comment/post">
        <input type="hidden" name="post_key" value="{{ post.key }}"/>
        <p><label>Name:</label> <input type="text" name="author"/></p>
        <p><label>Comment:</label><br/><textarea name="comment"></textarea></p>
        <p><input type="submit" value="Leave comment"/></p>
      </form>
      <hr/>
    {% else %}
      <h1>Article Not Found</h1>
    {% endif %}
    <a href="/">&laquo; Back</a>

    赤くハイライトされた部分が記事に関するコメントです。  post.comments フィールドはリファレンスをcomment モデルに宣言したことによって作成されました。

  7. おわり

    これで、とてもとてもシンプルなブログシステムが完成しました