【问题标题】:Django template context function without running automaticallyDjango模板上下文功能不自动运行
【发布时间】:2011-01-19 15:03:52
【问题描述】:

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

我有一个函数:

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>,而不是运行它。

【问题讨论】:

    标签: django django-templates django-context


    【解决方案1】:

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

    但回答您的问题:您可以制作代理对象。例如:

    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 }}
    

    你可以让它更加通用,并创建具有一个方法的代理类(例如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 }}
    

    【讨论】:

    • 这个解决方案是我在外面抽烟时突然想到的。并不是说我有任何功劳,只是说,我完全同意;这看起来是最好的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2020-11-08
    相关资源
    最近更新 更多