GAE笔记(一) 入门和环境

重新玩下GAE,以前做的全忘了

重头开始吧

一些资源

下载: http://code.google.com/intl/zh-CN/appengine/downloads.html

文档: http://code.google.com/intl/zh-CN/appengine/docs/

1 直奔helloworld

解压google_appengine_1.3.8.zip就可以了

[ccn lang="bash" tab_size="4" theme="blackboard" width="800"]

$ mkdir -p ~/workpsace/gae_helloworld

[/ccn]

[ccn lang="bash" tab_size="4" theme="blackboard" width="800"]

# emacs ~/workpsace/gae_helloworld/helloworld.py

[/ccn]

添加以下内容

[ccn lang="python" tab_size="4" theme="blackboard" width="800"]

print 'Content-Type: text/plain'
print ''
print 'Hello, world!'

[/ccn]

创建配置文件

[ccn lang="bash" tab_size="4" theme="blackboard" width="800"]

application: helloworld
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
script: helloworld.py

[/ccn]

本地测试应用程序

用法可以参考 http://code.google.com/intl/zh-CN/appengine/docs/python/tools/devserver.html

[ccn lang="bash" tab_size="4" theme="blackboard" width="800"]

$ google_appengine1.3.8/dev_appserver.py --port=16001 --address=192.168.3.137 -d workpsace/gae_helloworld/

[/ccn]

现在就可以在浏览器访问了

2 使用web框架

修改helloworld.py

[ccn lang="python" tab_size="4" theme="blackboard" width="800"]

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')

application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()

[/ccn]

然后重启

3 使用用户系统

修改helloworld.py

[ccn lang="python" tab_size="4" theme="blackboard" width="800"]

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()

if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))

application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()

[/ccn]

应用程序会将您重定向到适用于测试应用程序的 Google 登录页面的本地版本。您可以在该屏幕中输入自己喜欢的任何用户名,应用程序会基于该用户名发现伪造 User 对象。
当应用程序在 App Engine 上运行时,用户会被定向到 Google 帐户登录页面,然后在成功登录或创建帐户后重定向到应用程序。

其中

user = users.get_current_user()
如果用户已登录到您的应用程序,get_current_user() 将为用户返回 User 对象。否则,它会返回 None。

if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
如果用户已登录,将使用与用户的帐户关联的昵称显示个性化的消息。
else:
self.redirect(users.create_login_url(self.request.uri))
如果用户尚未登录,则通知 webapp 将用户的浏览器重定向到 Google 帐户登录屏幕。这种重新定位包括本页面的网址 (self.request.uri),
因此用户登录或注册了新帐户后,Google 帐户登录机制会引导用户返回到此处。

4  表单处理

修改helloworld的内容为以下

[ccn lang="python" tab_size="4" theme="blackboard" width="800"]
import cgi

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<body>
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>""")
class Guestbook(webapp.RequestHandler):
def post(self):
self.response.out.write('<html><body>You wrote:<pre>')
self.response.out.write(cgi.escape(self.request.get('content')))
self.response.out.write('</pre></body></html>')

application = webapp.WSGIApplication(
[('/', MainPage),
('/sign', Guestbook)],
debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()

[/ccn]

webapp.WSGIApplication这个方法里为url添加了一些处理的类的相对应的映射关系
[ccn lang="python" tab_size="4" theme="blackboard" width="800"]
application = webapp.WSGIApplication(
[('/', MainPage),
('/sign', Guestbook)],
debug=True)
[/ccn]

cgi.escape() 来将 HTML 特殊字符转义为相应的对等字符实体
[ccn lang="python" tab_size="4" theme="blackboard" width="800"]
self.response.out.write(cgi.escape(self.request.get('content')))
[/ccn]
get和post方法分别对应相对应的url和方法

5