Django模板上下文功能无需自动运行

时间:2010-02-22 12:25:06

标签: django django-templates django-context

抱歉或令人困惑的标题!它实际上比听起来简单得多。

我有一个功能:

def get_messages(request):
    # do something expensive with the request
    return 'string'

我希望能够从模板中调用该函数,因此我使用了上下文处理器:

def context_processor(request):
    return {'messages':get_messages(request)}

现在,当我的模板中有{{messages}}时,string会打印出来。大。

问题是get_messages非常昂贵,并不总是需要。不到一半的模板需要它。有没有办法将函数传递给模板,如果它运行与否则将其留给模板?

我已经尝试过了:

def context_processor(request):
    return {'messages':get_messages}

但是这只是在模板中输出函数描述<function get_messages at 0x23e97d0>而不是运行它。

1 个答案:

答案 0 :(得分:3)

我认为你不应该将应用程序的逻辑与模板混合(MVC模式中的视图)。这打破了架构的一致性。您可以在需要它的视图中调用get_messages,只需将messages传递给模板上下文,其他人只需传递None

但回答你的问题:你可以制作代理对象。 E.g:

class Proxy(object):
    def __init__(self, request)
        self.request = request
        super(Proxy, self).__init__()

    def get_messages(self):
        # so some expensive things
        return 'string'

# context processor
def context_processor(request):
    return {'messages':Proxy(request)}

# in the view
{{ messages.get_messages }}

你可以使它更通用,并创建具有一个方法的Proxy类(例如get),并在构造函数中获取一个参数:一个将请求对象作为第一个参数的函数。这样您就获得了在模板中代理函数调用的通用方法。这是:

class Proxy(object):
    def __init__(self, request, function)
        self.request = request
        self.function = function
        super(Proxy, self).__init__()

    def get(self):
        return self.function(self.request)

然后你可以写得比我之前写的更酷:

# context processor
def context_processor(request):
    return {'messages':Proxy(request, get_messages)}

# sounds nice to me
{{ messages.get }}