最近忙,本来计划的一篇技术文章写了很久没写完,先发一篇短文凑数。
以前用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]