8

鉴于以下情况:

from django.shortcuts import render


def decorator(view):
    def wrapper(request, *args, **kwargs):
        context = {'foo': 'bar'}
        # Logic ...
        return view(request, *args, **kwargs)
    return wrapper


@decorator
def index(request):
    return render(request, 'index.html')

我想让装饰器在视图中添加一个上下文字典,以便返回的装饰函数如下所示:

return render(request, 'index.html', context)

这可能吗?

4

2 回答 2

7

经过一堆搜索后,我想出了如何以一种不需要在原始函数中添加额外内容的方式来做到这一点,从而保持干燥。关键是 Django 的TemplateResponse对象,它将模板的呈现推迟到将响应发送给用户之前,从而为装饰器(和中间件,FWIW)的处理提供了机会。

这是它现在的样子:

from django.template.response import TemplateResponse    

def decorator(view):
    def wrapper(request, *args, **kwargs):
        r = view(request, *args, **kwargs)
        r.context_data = {'foo': 'bar'}
        return r.render()
    return wrapper

@decorator
def index(request):
    return TemplateResponse(request, 'index.html')
于 2013-06-18T20:56:29.250 回答
5

这不可能是您当前编写函数的方式,但您可以针对相同的行为执行以下操作:

from django.shortcuts import render    

def decorator(view):
    def wrapper(request, *args, **kwargs):
        context = {'foo': 'bar'}
        args = args + (context,)
        return view(request, *args, **kwargs)
    return wrapper    

@decorator
def index(request, *args):
    return render(request, 'index.html', *args)

这将导致装饰器将您的context字典添加到传递给的位置参数的末尾,index()然后传递给render().

于 2013-06-18T19:05:12.017 回答