Create projectAs the previous section mentioned, let's use gaeo.py to create a gbook application.# gaeo gbook
Message FormFirst, we create a form for the visitor to leave messages. The root page (url '/') is default dispatched to the welcome controller and index action. That means if you want to do anything on the root page, you need to add codes in the welcome controller.The welcome controller is a WelcomeController class, which locates in the application/controller/welcome.py [1]. Now, the content of welcome.py should be like this: from gaeo.controller import BaseController
class WelcomeController(BaseController): def index(self): pass There's a WelcomeController class with a index method. Yeah, the index method stands for the handler of index action. Now, just leave it blank (i.e. one line code -- pass) at this time. Since the URL '/' is dispatched to welcome controller and index action, the default output is the application/templates/welcome/index.html template. Let's add a form in this file with the following content: <!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> Thus, we create a web form with 2 fields, one is used to fill the visitor's name and the other is her message. While the visitor pushes the Post button, the form sends a HTTP Post request to the URL '/speak'. Now, we have to handle this request. Add routing rulesAlthough GAEO has default URL routing rules (for example, '/' is dispatched to {'controller': 'welcome', 'action': 'index'}), there's no default rule for URL '/speak'. It's easy to add a custom rule in your application. Open the main.py file and find the initRoutes method:def initRoutes():
r = router.Router() #TODO: add routes here r.connect('/:controller/:action/:id') The above code is generated by the gaeo.py script. We may add the rule of URL '/speak' here as the following def initRoutes():
r = router.Router() r.connect('/speak', controller='welcome', action='speak') r.connect('/:controller/:action/:id') After adding the line of code, the URL '/speak', now, will be dispatched to welcome controller and speak action. So, we have to add a speak method in the WelcomeController class for handling the '/speak' requests. Store the dataBefore we implementing the speak method, let's specify the data model first. In your application's directory root (e.g., /home/ericsk/Demos/gbook), use gaeogen.py script to generate a data model class with this command:gaeogen model Message
The first argument is the type of generation and the second is the name of data model. The above command generates a Message class in the application/models/message.py file. It should be from google.appengine.ext import db
from gaeo.model import BaseModel class Message(BaseModel): pass Besides generating the model, we have to define which data we want to store in this model. So we add some codes like this: 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) We stores 3 fields in this mode:
Process and store the dataLet's get back the speak action. Since we add a custom rule that makes URL '/speak' be dispatched to {'controller':'welcome', 'action':'speak'}, we have to add a speak method in the WelcomeController:# 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) It's simple to store a data in the App Engine's bigtable -- create a model instance and invoke put method to store it. The requested data (from the message form) are stored in the self.params object (it's a dict) and the key is mapped to the form field's name property. While we complete storing the data, we redirect the request to the URL '/'. If there's an error occurred, the except block will show the exception message to the brower through self.render method. Check the storageBefore we presenting the messages, we should check if the data are correctly stored in the bigtable. You can visit http://localhost:8080/_ah/admin/datastore to check the storage (on your machine). In the Entity Kind: field, type Message to see all the stored Message data.If you are using the Launcher, you can visit this page via the SDK Console tab. Present the stored messagesIf the messages are correctly stored, we can show them on the page in a readable format. If we want to show the message in the root page, we have to fetch the data in the 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) ... We added an instance variable in the controller and this variable will be sent to the template for rendering. Now, open the index's template to show the messages. <!-- 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> ... ... Finally, we have a simple guestbook application, now. |