【问题标题】:Django: add context to response using decoratorDjango:使用装饰器为响应添加上下文
【发布时间】:2013-06-15 03:11:19
【问题描述】:

鉴于以下情况:

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)

这可能吗?

【问题讨论】:

  • 是的,当然。这是可能的。有很多视图函数 decotarors。 here你是某人
  • 这正是ContextProcessors 的用途。
  • 对于所有模板:上下文处理器。对于某些视图:装饰器
  • @J0HN 上下文处理器没有应用于每个视图吗?我正在专门寻找一种可以按观看次数应用的解决方案。

标签: python django decorator


【解决方案1】:

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

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()

【讨论】:

    【解决方案2】:

    经过大量搜索,我想出了如何以一种不需要在原始函数中添加额外内容并保持干燥的方式来执行此操作。关键是 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')
    

    【讨论】:

    • 你是对的,但要小心,因为响应并不总是 TemplateResponse。
    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多