In this application, you see how to use GAEO to build a Todo-List application. The application will show you the user authentication flows and process data of different users. Let's start by designing the mockup of this application. Design Phase--The Mockups--Design The Models--Implementation Phase--Create The ProjectTo start creating the project, you have to be sure that you've installed the Google App Engine SDK and (the current) GAEO packages. After preparing the necessary packages, you can create a project as the following command (use this command in your console):Command 1. Create The utodo Project. ~/$ gaeo utodo The gaeo script will create a utodo directory that includes the basic project files. The application's identifier is also utodo. Note that if you installed GAEO by unzipping the released package, maybe your script name is gaeo.py instead of gaeo. Define The ModelsLet's begin to design the models in this application. There are three models are necessary -- User, Todo, and Counter. The User model stores the user information; the Todo model stores all todo items; the Counter model is used to count the entries since the Bigtable isn't good at counting.Command 2 shows how to use gaeogen script to generate the model templates. Command 2. Use gaeogen To Generate Models Now you have user.py, todo.py and counter.py files in the ~/utodo/application/model directory. The Code 1 is the inplementation of these models.~/utodo$ gaeogen model User Creating Model user ... ... ~/utodo$ gaeogen model Todo Creating Model todo ... ... ~/utodo$ gaeogen model Counter Creating Model counter ... ... Code 1. Design The Models (user.py, todo.py, and counter.py) Since the todo item belongs to one user, we use the belongs_to method to construct the relationship between User/Todo model. In the remaining section, you will see how we specify a todo item to an user.# application/model/user.py from google.appengine.ext import db from gaeo.model import BaseModel class User(BaseModel): name = db.StringProperty(required=True) profile = db.StringProperty(multiline=True) created = db.DateTimeProperty(auto_now_add=True) # application/model/todo.py from google.appengine.ext import db from gaeo.model import BaseModel from model.user import User class Todo(BaseModel): title = db.StringProperty(required=True) desc = db.TextProperty(required=True) status = db.IntegerProperty(required=True, default=0) created = db.DateTimeProperty(auto_now_add=True) updated = db.DateTimeProperty(auto_now=True) Todo.belongs_to(User) # application/model/counter.py from google.appengine.ext import db from gaeo.model import BaseModel class Counter(BaseModel): name = db.StringProperty(required=True) count = db.IntegerProperty(required=True, default=0) The Welcome Page and User Sign-upIn the / page (Welcome controller and index action), we put a sign-in url for user login. The Google App Engine provides a Google account sign in/out api so that the user can login a Google App Engien application by using her Google (or Google Apps) account. In the utodo application, we connect the user model to a logined Google account. Now lets add the signin link in the welcome page. Code 2 shows the html:Code 2. Put Sign-in Link on the Welcome Page. (application/templates/welcome/index.html) <h1>utodo application</h1> <a href="{{signin_url}}">Sign in</a> to manage your Todo list. In this HTML file, we insert a link and the link is stored as template variable -- signin_url. We have assign value to this variable in the controller. Code 3 shows the assignment in the action. Code 3. Assign signin_url Value in Controller (application/controller/welcome.py) class WelcomeController(BaseController): def index(self): from google.appengine.api import users self.signin_url = users.create_login_url('/user/home') We create a Google account signin URL by using the App Engine's Users Service and specify a redirection to /user/home. That means if user successfully sign in with her Google account, the authentication page will redirect her to the http://yourhost.com/user/home. The /user/home URL stands for the GAEO router will dispatch the request to the home action in User controller. We can also create the User controller with the following command: Command 2. Create the User Controller. ~/utodo$ gaeogen controller User signup home Creating .... Code 5. Check If The User Is A New Comer. (application/controller/user.py) As you can see, we will use the Google account's email address to be the key_name of an utodo user entity (will be mentioned later). If the user hadn't signed up an utodo account, the utodo_user will be None and we take her to the /user/signup page.... def home(self): from google.appengine.api import users from model.user import User # retrieve the logined Google account information google_acct = users.get_currnet_user() # TODO: if google_acct is None, take to the login page # get an user entity with the email address utodo_user = User.get_by_key_name(google_acct.email()) if utodo_user is None: self.redirect('/user/signup') Now, put a sign-up form in the /user/signup page. Code 6. Add a Sign-up Form. (application/templates/user/signup.html) <form method="post" action="/user/create"> <fieldset> <legend>Sign Up An Utodo Account</legend> <p> <label>Name:</label><br> <input type="text" name="user[name]" id="user_name"> </p> <p> <label>Profile:</label><br> <textarea name="user[profile]" id="user_profile" rows="3" cols="40"></textarea> </p> <p> <input type="submit" value="Sign Up"> </p> </fieldset> </form> The form data will be sent to the /user/create to create an utodo account. So we add the create action in the User controller as Code 7. Code 7. The /user/create Action (application/controller/user.py) .... def create(self): from google.appengine.api import users from model.user import User from model.counter import Counter # retrieve the form data data = self.params['user'] google_acct = users.get_current_user() # create a user entity and set the key_name to the # Google account's email address. u = User(key_name=google_acct.email(), name=data['name'], profile=data['profile']) u.put() # add user counter c = Counter.get_by_key_name('user') if c is None: c = Counter(key_name='user', name='user') c.count += 1 c.put() # redirect to /user/home self.redirect('/user/home') In the create action, we create an utodo user according to the data sent from sign-up form. Since we specify the form field names as an user array, we can retrieve the array through self.params and it returns an array, too. After creating the user entity, it takes user to /user/home page. In current step, we leave /user/home blank first. Let's process Todo items now. |