touchmm 发表于 2013-2-7 19:55:46

给web.py加点仿TG的功能

最近忙,本来计划的一篇技术文章写了很久没写完,先发一篇短文凑数。
以前用Turbogears 1.x的时候觉得它有一些功能真是很方便,比如expose decorator。不过现在用web.py就没有这种东西了。
话说我改用web.py就是图它比较清爽这个优点,但能增加点方便还是好的。其实这个功能实现起来挺简单的,于是这两天就给web.py写了一个。
另外,现在RESTful的API都喜欢提供多种格式的结果返回(貌似这是twitter引领的风潮),于是顺便也给自己写的这个东东增加了这样的功能。
代码如下(其中obj2xml的代码来自这里):
import jsonimport webfrom web.contrib.template import render_makoclass TGBaseHandler:    def __init__(self, templates_path):      self.mako_render = render_mako(            directories=,            input_encoding='utf-8',            output_encoding='utf-8'      )    # 默认支持两种 format render    # html render 使用 mako 模板    def html_render(self, page, result):      return getattr(self.mako_render, page)(**result)    def json_render(self, page, result):      return json.dumps(result)    # 自动调用相应的 format render    def render(self, page, format, result):      try:            render_func=getattr(self, format + '_render')      except AttributeError:            raise "Invalide render format!"      return render_func(page, result)# format : html/json/xml...# 默认为 html format,只需要提供 page 参数,其它 format 可以不需要 page 参数def expose(page='', format='html'):    def expose_wrapper(fn):      def format_wrapper(self, *args, **kwargs):            result=fn(self, *args, **kwargs)            if 'format' in result.keys(): # 自动选择相应的 format                format = result['format']                del result['format']            return self.render(page, format, result)      return format_wrapper    return expose_wrapper
用法如下:
#...import obj2xmlurls = (      "/", "index",      "/index", "index",      "/jsondata", "jsondata",      "/timeline\.?([^/?\.]+)", "timeline", # 自动取得 format 参数      )#...class BaseHandler(TGBaseHandler):    def __init__(self):      TGBaseHandler.__init__(self, ‘pathto/templates’) # 初始化 mako    # 可以在这里添加各种自定义的 format render    def xml_render(self, page, result):      return obj2xml.getXML(result)class index(BaseHandler):    @expose("index") # 默认 format 为 html    def GET(self):      return dict(url="/")class jsondata(BaseHandler):    @expose(format='json') # 指定用 json format render    def GET(self):      return dict(tweets=[{'id':'1234','text':'hello'},{'id':'2345','text':'world'}])class timeline(BaseHandler):    @expose() # 自动选择 format render    def GET(self, format):      return dict(format=format, tweets=[{'id':'1234','text':'hello'},{'id':'2345','text':'world'}]) # 注意,要在这里返回 format 参数
这样访问 index 页面时返回的是用mako render出来的HTML,访问 jsondata 页面返回的就是一个 JSON 文本,访问 timeline.xml 和 timeline.json 就可以分别返回 XML 和 JSON 文本。
另外Turbogears 1.x的identity也很赞,回头有空也弄一个给web.py。
推送到
页: [1]
查看完整版本: 给web.py加点仿TG的功能