[!] 注意 如果你在 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個欄位:
處理、儲存資料在完成 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> ... ... 一個簡單的留言程式便完成了。 |