2010-02-22 67 views
2

抱歉或令人困惑的標題!它實際上比聽起來簡單得多。Django模板上下文功能沒有自動運行

我有一個功能:

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

回答

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

你可以讓這個越來越普通,並創建有一個方法代理類(例如get),以及發生在構造函數中的一個參數:這需要request對象作爲第一個參數的函數。通過這種方式,您可以獲得泛型方法來代理模板中的函數調用。那就是:

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

該解決方案同時具有憂鬱的香菸只是發生在我之外。並不是說我有任何信用,而只是說,我完全同意;這看起來像是最好的解決方案! – Oli 2010-02-22 12:37:11