给web.py加点仿TG的功能

  猛禽
  Python相关
  2011-01-04
  增加更多TAG »
  4,600次

最近忙,本来计划的一篇技术文章写了很久没写完,先发一篇短文凑数。

以前用Turbogears 1.x的时候觉得它有一些功能真是很方便,比如expose decorator。不过现在用web.py就没有这种东西了。

话说我改用web.py就是图它比较清爽这个优点,但能增加点方便还是好的。其实这个功能实现起来挺简单的,于是这两天就给web.py写了一个。

另外,现在RESTful的API都喜欢提供多种格式的结果返回(貌似这是twitter引领的风潮),于是顺便也给自己写的这个东东增加了这样的功能。

代码如下(其中obj2xml的代码来自这里):

import json
import web
from web.contrib.template import render_mako

class TGBaseHandler:
    def __init__(self, templates_path):
        self.mako_render = render_mako(
            directories=[templates_path,],
            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 obj2xml

urls = (
        "/", "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。

推送到[go4pro.org]


除非另有来自Go4Pro.org或原作者的显式声明,本站点所有文章都按照知识共享许可协议知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议进行许可。

Go4Pro.org,V3.0,2009-2014。本站点采用SymfonyBootstrapTwig等技术开发。