web.py 是python的一款web开发框架,小巧,简单,实用。写简单的web页面,web.py可以快速的完成,你只需了解它的MTV(model,template,view)工作模式就好了。gae中默认是支持django的,这个框架开发效率很好,对我们有些小应用来说还是太重了。所以webpy是个不错的选择。
由于web.py自带的模板用起来并不是很爽,可以选择mako作为开发模板。把web.py和mako的包放到工程中,关于web.py的具体工作内容可以参考官方的文档,有需要的时候查看一下即可。在结合gae开发的过程中会碰到的问题做一些探讨。
Session的存储
由于web.py支持文件和数据库存储,gae不支持本地文件存储session,所以只能找到他的memcache作为session的存储地,所以需要重写web.session中的Store类来达到在gae中存储session的目的。
from web.session import Store
import web
import time
class MemcacheStore(Store):
def __init__(self, memcache):
self.memcache = memcache
def __contains__(self, key):
data = self.memcache.get(key)
return bool(data)
def __getitem__(self, key):
now = time.time()
value = self.memcache.get(key)
if not value:
raise KeyError
else:
value['attime'] = now
self.memcache.replace(key,value)
return value
def __setitem__(self, key, value):
now = time.time()
value['attime'] = now
s = self.memcache.get(key)
if s:
#value = dict(map(lambda x: (str(x[0]), x[1]), [(k, v) for (k, v) in value.iteritems() if k not in ['_id']]))
self.memcache.replace(key,value)
else:
self.memcache.add(key,value,int(web.config.session_parameters['timeout'][0]))
def __delitem__(self, key):
self.memcache.delete(key)
def cleanup(self, timeout):
#timeout = timeout / (24.0 * 60 * 60)
#last_allowed_time = time.time() - timeout
#self.collection.remove({'attime' : { '$lt' : last_allowed_time}})
#automatic cleanup the session
#self.memcache.flush_all()
pass
模板的生成
web.py templetor 把模板编译成 python 字节码,这需要访问标准库中的 parser 模块。不幸的是,由于安全原因 GAE 禁用了这个模块。
为了克服这个状况,web.py 支持把模板编译成 python 代码,从而避免在 GAE 上使用原来的模板。web.py 确保在应用这种方法的时候模板中的代码不需要任何改变。
为了编译一个文件夹中所有的模板(一旦有模板改动,就需要重新运行),运行:
$ python web/template.py --compile templates
以上命令把 templates/ 目录下的模板文件递归地全部编译,并且生产 __init__.py, 'web.template.render` 重新编写过,它将视 templates 为一个 python 模块。
配置的问题
由于web.py的静态文件需要放在根目录的static下面,所以需要在yaml配置中对css,js,images做相关的配置处理,否则gae无法通过web.py来正确的解析相关的配置。
- url: /css
mime_type: text/css
expiration: 10000d
static_dir: static/css
- url: /images
expiration: 10000d
static_dir: static/images
- url: /js
static_dir: static/js
expiration: 10000d