使用 Python 2.7 作为 GAE 运行时
GAE 支持 Python 2.7 也有段时间了, 考虑到 2.7 加入了很多有意思的东西, 其中一些特性是先在 Python 3 里面出现, 然后移到 2.7 里面来的, 如 - 有序字典 (而非默认的散列字典) 类型, 如
collections.OrderedDict({ 1: 'abc', 2: 'def' }) - 集合类型字面常量, 如
{ 1, 2, 3 } (以前版本写作 set([1, 2, 3]) ) - 字典及集合类型的推导式 (这么翻译准确么? Set / dictionary comprehensions), 如
{ x: x * x for x in range(5) }
要简单地将运行时环境切换到 Python 2.7 版本, 需要修改 app.yaml 为如下形式 application: YOUR APP ID version: YOUR APP VERSION runtime: python27 threadsafe: false api_version: 1
此外需要修改应用程序启动代码, 类似如下方式 from google.appengine.ext import webapp from google.appengine.ext.webapp import template import wsgiref.handlers import webapp2
class Index(webapp.RequestHandler): def get(self): print 'Hello'
if __name__ == '__main__': application = webapp2.WSGIApplication([ ('/', Index), ], debug=True) wsgiref.handlers.CGIHandler().run(application)
使用 2.7 版本的另一个好处是 GAE 上为 2.7 版本提供了很多库支持, 包括 jinja (这样就可以摆脱 django 模板了 :-). 如果需要引用 jinja2 库最近版本, 需要在 app.yaml 中加入以下内容 application: YOUR APP ID version: YOUR APP VERSION runtime: python27 threadsafe: false api_version: 1
handlers: - url: /.* script: main.py
libraries: - name: jinja2 version: latest
libraries 下面还可以附上其它想要使用的库. 在 此处可以查看所有 Python 2.7 运行时所支持的库.
Posted at Jul 30 2012 - 03:59:13
Permanent Link:
/p/492
Load full text
|
Post tags:
Google AppEngine
Python
|
还是低调地给博客写个应用文档
NijiPress 你现在就在浏览 (如果不是通过 Reader 之类的查看这篇文章的话) 我自制的, 山寨 WordPress 的, 实际上挂载在 Google AppEngine 上的, 文章格式完全靠 markdown 的 NijiPress 系统上的文章. (即使通过 Reader, 你看到的文章内容版式也是经由 markdown 转换的结果) 这篇文章将谈谈其中的 markdown 语法. NijiText NijiPress 的 markdown 内核叫做 NijiText. 不得不说 NijiText 中有些 markdown 语法确实很非主流, 对于下面出现的各种魑魅魍魉, 还请高抬贵槽. 行中转换超链接@@ http://example.org/ @Example@@ ==> Example语法为 @@链接@文字@@. 强调将文字包入 strong 标签 **需要加粗的文字** ==> 需要加粗的文字行中代码将文字包入 tt 标签 ``text im+-*/`` ==> text im+-*/ 这里的引号为标准键盘主键区数字 1 左边那个. 上下标将文字包入 sub 或 sup 标签 ,,下标,, ^^上标^^ a,,2,,x^^2^^+a,,1,,x+a,,0,,=0 ==> a 2x 2+a 1x+a 0=0 删除线将文字包入 s 标签 --删除线-- ==> 删除线斜体将文字包入 i 标签 ///italic/// ==> italic因为许多编程语言中, 双斜杠 // 表示单行注释, 为了避免纠结的转义, 所以斜体设计为三个斜杠. 转义将反斜杠放在与 markdown 语法相关的特殊字符前转义该字符 这段文字 *\* 不会被加粗, *\* 反斜杠本身 \\ 转义 ==> 这段文字 ** 不会被加粗 **, 反斜杠本身 \ 转义 Headings当某一行由 1~3 个等号 (=) 开头, 且等号后加上一个空格, 那么这些符号之后的内容将被转换为标题. = Heading 1 == Heading 2 === Heading 3 代码块用仅 {{{ 和仅 }}} 将多行内容括起来时, 中间的内容将会变为一个代码块 {{{ code line 0 code line 1 }}} ==> code line 0 code line 1
ASCII Art如果一行由一个冒号一个空格开头, 这一行将被解析为一行 AA 内容. AA 内容中的转义字符 (\) 和任何行中转义将被忽略. 连续多个这样的行将被合并为一块 AA 内容. : . | : |\ | : | \| : | `
==> . | |\ | | \| | `
表格用仅 [[[ 和仅 ]]] 将多行内容括起来时, 中间的内容将会变为一个表格, 每行内容将被转换成一个 tr. 中间的单元格用 || 分隔. 下面是一些例子 一般表格: [[[ ||单元格||单元格 ||第二行||... ]]] ==> 更复杂地, 为单元格加上跨行跨列内容对齐等属性: [[[ || ;hcr2;hori-align 为 top 且跨 2 行||cell ||row 2||... ||row 333333333333333333333333333333||... ]]] ==> hori-align 为 center 且跨 2 行 | cell | row 2 | ... | row 333333333333333333333333333333 | ... |
Posted at Feb 22 2012 - 15:28:54
Permanent Link:
/p/482
Load full text
|
Post tags:
Google AppEngine
NijiPress
Markdown
|
GAE 速成简易博客 - 简化 RequestHandler
上节回顾 - 进阶数据库操作在 index.py 和 single_post.py 中, 请求处理器 Index 跟 SinglePost 的代码重复的部分还是挺多的 class SinglePost(webapp.RequestHandler): def get(self): path = os.path.join(os.path.dirname(__file__), 'templates/single_post.html') posts = db.GqlQuery('SELECT * FROM Post WHERE pid = :1', int(self.request.get('id'))) self.response.out.write(template.render(path, { 'post': posts[0], }))
class Index(webapp.RequestHandler): def get(self): path = os.path.join(os.path.dirname(__file__), 'templates/index.html') posts = db.GqlQuery('SELECT * FROM Post ORDER BY date DESC') self.response.out.write(template.render(path, { 'posts': posts, }))
作为程序员, 应该对这样的重复代码零容忍, 当机立断, 大刀阔斧来改起! 从上面的对比看来, 很明显, 对于日常情况中的请求, 服务器端重要的的响应参数包括 那么很好, 来弄个基类, 新建个 base.py 放进去 from google.appengine.ext import webapp from google.appengine.ext.webapp import template import os
class BaseHandler(webapp.RequestHandler): def put_page(self, templ_file, templ_args): path = os.path.join(os.path.dirname(__file__), templ_file) self.response.out.write(template.render(path, templ_args))
开始用新的 BaseHandler 搞起吧. 先来搞 index.py
Posted at Jan 23 2012 - 07:17:09
Permanent Link:
/p/480
Load full text
|
Post tags:
Web Server
Google AppEngine
Tutorial
Python
|
GAE 速成简易博客 - 更多数据库操作
上节回顾 - 表单处理与基本的数据库操作现在首页能显示文章列表了, 但是 - 文章的顺序貌似是乱的, 而一般来说, 博客系统会按照发布的时间先后顺序来放置
- 构造一个页面, 看指定的某一篇文章的内容
那么, 现在就开始修改数据库吧. 为文章加上 ID 和日期添加属性修改 model.py class Post(db.Model): pid = db.IntegerProperty() title = db.StringProperty(multiline=False) content = db.TextProperty() date = db.DateTimeProperty(auto_now_add=True)
def put_post(title, content):
其中 pid 表示 post id, 是一篇文章的唯一标识; date 是文章的发布时间, 它被设置为对象被存入数据库时自动设置为当前时间 ( auto_now_add=True ). 在 GAE 存储中, 并没有类似 auto_increment 的设置, 因此 pid 的管理需手动进行. 在数据库中, GAE 也有给每个对象设置一个全局唯一的 id , 可以通过如 post.key().id() 来获取, 但是这样获取的 id 值在发布服务器上没有规律可言, 不具备有序性, 不建议使用. 按 ID 排序查询和自增 ID刚刚为 Post 添加的两个属性中, date 是会自动添加到数据库中的, 但 pid 并不会, 得手动给加上. 想要实现自增 ID 的功能, 一个简单的思路是, 从数据库中取出 pid 最大的那篇, 在它的基础上 +1 赋值给新文章即可. 那么继续修改 model.py def next_post_id(): posts = db.GqlQuery('SELECT * FROM Post ORDER BY pid DESC') return 0 if posts.count() == 0 else posts[0].pid + 1
def put_post(title, content): post = Post() post.pid = next_post_id() post.title = title post.content = content post.put()
这里 GQL 中的 ORDER BY pid DESC 表示按照 pid 排序, 而且是降序排列. 另外, 还得修改 add_post.py 里的 AddPostHandler 不能让它乱来了, 而应该改为调用 put_post class AddPostHandler(webapp.RequestHandler): def post(self): # new_post = model.Post() # new_post.title = self.request.get('title') # new_post.content = self.request.get('content') # new_post.put() model.put_post(self.request.get('title'), self.request.get('content')) self.redirect('/add_post')
Posted at Jan 20 2012 - 11:43:58
Permanent Link:
/p/478
Load full text
|
Post tags:
Web Server
Python
Tutorial
Google AppEngine
|
GAE 速成简易博客 - 表单处理与数据存取
上节回顾 - 站点基本配置与模板没有数据滋养的首页还是个半残废, 下面开始折腾数据库. 添加文章入口 虽然添加文章这种事情可以直接通过后台暴力搞数据库来做, 但既然要写的是 Web 应用, 那么写个页面提供添加文章的入口也是理所当然的事情. 页面嘛, 肯定得有个 HTML 模板撑着, 来建个文件, templates/add_post.html <html> <head><title>Add Post</title></head> <body> <form> <table> <tr><td>Title</td><td><input type='text' name='title'></td></tr> <tr><td style='vertical-align: top;'>Content</td> <td><textarea name='content'></textarea></td></tr> <tr><td><input type='submit'/></td></tr> </table> </form>
接下来得增加一个 RequestHandler , 新建文件 add_post.py from google.appengine.ext import webapp from google.appengine.ext.webapp import template import os
class AddPostEntry(webapp.RequestHandler): def get(self): path = os.path.join(os.path.dirname(__file__), 'templates/add_post.html') self.response.out.write(template.render(path, dict()))
这个文件看起来与 index.py 差不多, 只不过因为 add_post.html 不需要参数, 因此传入 render 的字典是空字典. 最后在 main.py 中新增一项, 将一个 URL 映射到 AddPostEntry import wsgiref.handlers from google.appengine.ext import webapp
import index import add_post
if __name__ == '__main__': application = webapp.WSGIApplication([ ('/', index.Index), ('/add_post', add_post.AddPostEntry), ], debug=True) wsgiref.handlers.CGIHandler().run(application)
现在访问 http://localhost:8080/add_post/, 就可以看到这个入口页面了. 不过因为表单还没有设置处理者, 因此点破提交按钮就没有反应的. 处理表单 还是得添加一个处理请求的类, 修改 add_post.py, 加入这个类 import model
class AddPostHandler(webapp.RequestHandler): def post(self): new_post = model.Post() new_post.title = self.request.get('title') new_post.content = self.request.get('content') new_post.put() self.redirect('/add_post')
Posted at Jan 19 2012 - 03:31:17
Permanent Link:
/p/477
Load full text
|
Post tags:
Web Server
Tutorial
Google AppEngine
Python
|
GAE 速成简易博客 - 开张
前期准备目前 GAE 官方推荐的 Python 版本是 2.7 (终于脱离了 2.5 的泥潭啊), 实际上 2.6.x 版本也是没问题的 (写个 CMS 这种简易的设备, 应该还用不到太多高端的语言特性). GAE 当然也是必不可少的. 下载和安装步骤在 Google Code 上都有 详细文档. 如果使用 ArchLinux, 还可以通过 AUR 安装. 这里就不废话了. 找个地方, 建立一个目录, 比如叫做 cms-build, 切到这个目录作为工作目录. 下面开始. 数据结构既然是写博客, 那么最关键的当然要是文章 (post) 了. 先来建立用于定义数据的源文件 model.py from google.appengine.ext import db
class Post(db.Model): title = db.StringProperty(multiline=False) content = db.TextProperty()
每篇文章的基本属性有标题 title , 内容 content 和创建时间 date . 其中标题不允许多行; 而内容使用 db.TextProperty 类型而不是 db.StringProperty (根据 GAE 文档, StringProperty 只能存至多 500 字符). 首页模板 首先, 将首页给弄出来, 建立目录 templates, 并在这个目录下弄一个 index.html 文件, 内容是 <html> <head><title>My Blog</title></head> <body> {% for post in posts %} <h1>{{ post.title }}</h1> <p>{{ post.content }}</p> {% endfor %}
在 GAE 中, HTML 模板文件使用的是 django 的模板语法. 上面文件中, {% for ... %} 到 {% endfor %} 是对传入模板的参数 posts 的迭代. {{ post.title }} 则是对 post 对象的 title 的引用, 而 {{ post.content }} 则是引用 content . 简而言之 {% xxx %} 是模板中的控制语句, 而 {{ xxx }} 则是引用值. 在 django 官方网站可以看到 详细文档, 鄙博客之前也对 django 有过 简介. 这个首页是简单了点, 不过呢, 先看看样子. 视图源文件 光有 HTML 模板还不行, 至少, Python 源代码才是核心. 现在添加一个 Python 源文件 index.py
Posted at Jan 19 2012 - 03:30:27
Permanent Link:
/p/476
Load full text
|
Post tags:
Tutorial
Web Server
Template
Python
Google AppEngine
|