一个很有用的Django装饰器: render_to

2009-12-04 17:52

今天在pypi里面乱逛时看到一个装饰器, 觉得比较赞:

def render_to(template=None):
"""
    Decorator for Django views that sends returned dict to render_to_response function.

    Template name can be decorator parameter or TEMPLATE item in returned dictionary.
    RequestContext always added as context instance.
    If view doesn't return dict then decorator simply returns output.

    Parameters:
     - template: template name to use

    Examples:
    # 1. Template name in decorator parameters

    @render_to('template.html')
    def foo(request):
        bar = Bar.object.all()  
        return {'bar': bar}

    # equals to 
    def foo(request):
        bar = Bar.object.all()  
        return render_to_response('template.html', 
                                  {'bar': bar}, 
                                  context_instance=RequestContext(request))
    # 2. Template name as TEMPLATE item value in return dictionary

    @render_to()
    def foo(request, category):
        template_name = '%s.html' % category
        return {'bar': bar, 'TEMPLATE': template_name}
    
    #equals to
    def foo(request, category):
        template_name = '%s.html' % category
        return render_to_response(template_name, 
                                  {'bar': bar}, 
                                  context_instance=RequestContext(request))

    """
def renderer(function):
def wrapper(request, *args, **kwargs):
output = function(request, *args, **kwargs)
if not isinstance(output, dict):
return output
tmpl = output.pop('TEMPLATE', template)
return render_to_response(tmpl, output, context_instance=RequestContext(request))
return wrapper
return renderer

这个装饰器出自django-annoying. 在annoying目录下的decorators.py文件中.

优点: 写视图函数的时候, 总是写一个很长的render_to_response函数, 这个里面的东西都是很固定的. 于是每次都是y来p去, 很不爽. 如果用这个装饰器就可以很一目了然地在视图函数中用docstring里面的格式来写视图函数了. 这个时候, 视图函数返回一个字典就可以了.

缺点: 对于熟悉Django的用户, 这个可读性稍差了一点点. 不过我想习惯了这个装饰器的人都会更爱这个吧, 毕竟它更pythonic, 更DRY.