GAEO 正體中文文件

最新協作平台活動

教學‎ > ‎

create-a-simple-guestbook-application


[!]  注意

如果你在 Mac 下使用 eazy_install 安裝 GAEO,setuptools 會在 /usr/local/bin 下建一個 symlink 到 .py,指令會略有不同,例如 gaeo.py 會變成 
gaeo

建立專案

依照我們之前所提的,開始用 gaeo.py 來建立留言板應用程式吧!

gaeo.py gbook

留言表單

首先先建立可以讓訪客留言的表單。瀏覽網址 (url '/') 預設會被導到 welcome controller 的 index action. 你需要在 welcome controller 實作程式碼。
welcome controller 是一名為 WelcomeController 的 python class,放在 application/controller/welcome.py [1]. welcome.py 的內容應該長這樣:

from gaeo.controller import BaseController

class WelcomeController (BaseController):
     def index (self):
         pass

index method 負責處理  index action。現在什麼都不要修改,只留一個可以運作的空函式 ( 例:pass)
因為網址 URL '/' 已由 welcome controller 的 index action 負責顯示處理,預設是用 application/templates/welcome/index.html 作為樣板。現在在這個檔案裡建立一個內容如下的表單:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>GAEO Book</title>
    </head>
    <body>
      <form method="post" action="/speak">
        <fieldset>
            <legend>Leave a message</legend>
            <p>
                <label>Name:</label><br>
                <input type="text" name="username" size="20">
            </p>
            <p>
                <label>Message:</label><br>
                <textarea name="message" rows="5" cols="40"></textarea>
            </p>
            <p>
                <input type="submit" value="Post">
            </p>
        </fieldset>
      </form>
    </body>
</html>


然後建立兩個輸入框,一個用來填訪客名稱,另一個當然是用來寫留言的啦。當訪客點了Post按鈕。表單變會傳送 HTTP Post request 到 URL '/speak'。接下來要做的,便是撰寫 speak 這個 method的程式碼來處理傳遞過來的資料。

加入導向規則

儘管 GAEO 已建立了預設的導向規則 (例如, '/' 被指派為 {'controller': 'welcome', 'action': 'index'}),但 URL '/speak' 卻還沒有設定。 增加自訂規則的方法相當簡單。 開啟 main.py 然後找到 initRoutes 這個 method:

def initRoutes():
    r = router.Router()

    #TODO: add routes here

    r.connect('/:controller/:action/:id')

上面這段程式碼是由 gaeo.py script 產生,最下面的那一行作用為,對每一個 controller 裡的每一個 action 都傳遞一個名為 id 的參數,換言之,就是若 URL 是 '/foo/act/1',你可以在 controller foo裡的 act method 利用 self.param['id]' 來取得 1 。 初步認識導向規則後,現在加入 URL '/speak' 的規則如下:

def initRoutes():
    r = router.Router()
    r.connect('/speak', controller='welcome', action='speak')
    r.connect('/:controller/:action/:id')

完成上述動作後,URL '/speak' 便會被分派給 welcome controller 裡的 speak action。接下來便是實作 WelcomeController class 處理'/speak' requests。

儲存資料

 在實作 speak method 前,得先定義出 Data Model。在你應用程式根目錄裡 (例: /home/ericsk/Demos/gbook), 使用 gaeogen.py script 產生 Data Model class,鍵入指令:

gaeogen.py model Message

第一個參數為產生物種類,目前有 controller 、 model,第二個則為 Data Model 的名稱。上面這個指令會建立 application/models/message.py 以及 Message class 。 Message class 看起來如下:

from google.appengine.ext import db
from gaeo.model import BaseModel

class Message(BaseModel):
    pass

除了產生出 Model ,我們還要定義這個 Model 會儲存哪些資料,程式碼如下:

from google.appengine.ext import db
from gaeo.model import BaseModel

class Message(BaseModel):
    username = db.StringProperty(required=True)
    content = db.TextProperty(required=True)
    post_at = db.DateTimeProperty(auto_now_add=True)

j我們在這個 Model 儲存3個欄位:
  • username 訪客名稱。
  • content 留言內容。
  • post_at 留言時間。
這裡使用App Engine Datastore API 定義資料欄位型態。欲了解詳細使用方法,請閱讀 Google App Engine's API文件。

處理、儲存資料

在完成 Data Model 定義後,現在回到我們還沒實作的 speak action。 由於先前已將 URL '/speak' 指派到 {'controller':'welcome', 'action':'speak'},所以我們必須要在 WelcomeController 增加 speak method:

# application/controllers/welcome.py
from gaeo.controller import BaseController

# import the model class
from model.message import Message

class WelcomeController(BaseController):
    def index(self):
        pass
        
    def speak(self):
        try:
            # create a model instance and fill the data from request parameters
            msg = Message(
                    username=self.params['username'],
                    content=self.params['message']
                    )
            # store the data
            msg.put()
            # redirect to URL '/'
            self.redirect('/')
        except Exception, ex:
            # show the exception message
            self.render(text='Exception: %s' % ex)

在 App Engine's bigtable 儲存資料異常容易。-- 建立一個 model 物件然後呼叫 put method 儲存它自己。 requested data (從 message 表單傳遞過來) 被儲存在 self.params 物件 (資料型態:python dict) ,索引(key)名稱與表單欄位名稱相同, 當資料儲存後,我們會被導向 URL '/'.

而若有任何錯誤產生,self.render method 會在瀏覽器理顯示異常訊息。

檢查資料是否有被正確儲存

在顯示留言內容前,得先檢查資料是不是真地存進 bigtable。你可以連到 http://localhost:8080/_ah/admin/datastore 檢查資料 (存在你電腦裡)。選擇 Entity Kind: field,類別 Message 去觀看所有被儲存的 Message 資料。

如果你是使用 Launcher, 利用 SDK Console tab 連到此頁。

顯示被儲存的留言

我們想在根網址 '/' 顯示留言內容,便得在 index action 把資料撈出來:

# application/controllers/welcome.py
...

def index(self):
    # fetch all the messages
    self.msgs = Message.all()
    # sort them with the descending order of post_at
    self.msgs.order('-post_at')
    self.msgs.fetch(50)

...

我們在 controller 增加一個物件變數(instance variable),這個變數會自動傳遞給樣板檔案(template) ,以供你安排留言時間、留言內容,訪客名稱顯示的位置。

<!-- application/templates/welcome/index.html -->
...
...
<div id="messages">
  {% if msgs %}
  <ul>
    {% for msg in msgs %}
    <li>
      <h3>{{ msg.username }}:</h3>
      <p>{{ msg.content }}</p>
      <hr>
      <p style="text-align:right;"><small>At {{ msg.post_at|date }}</small></p>
    </li>
    {% endfor %}
  </ul>
  {% else %}
  <h1>There's no messages.</h1>
  {% endif %}
</div>
...
...

一個簡單的留言程式便完成了。