您可以直觀地檢查模板,並遵守任何「變量節點」物體的存在該模板中的節點列表:
>>> from django.template import Template, Context
>>> t = Template("Django is {{ adjective }} and I {{ verb }} it.")
>>> t.nodelist
[<Text Node: 'Django is '>, <Variable Node: adjective>, <Text Node: ' and I '>, <Variable Node: verb>, <Text Node: ' it.'>]
這些類型VariableNode
,這是可以直接導入在比較使用的一類。任何Node
實例都有一個get_nodes_by_type()
方法,可以針對nodelist調用該方法,該方法返回該模板的該類型的所有節點。例如:
>>> from django.template import VariableNode
>>> varnodes = t.nodelist.get_nodes_by_type(VariableNode)
>>> varnodes
[<Variable Node: adjective>, <Variable Node: verb>]
所以現在你有一個模板變量的列表。這將需要進一步提取每個變量的實際名稱,而不要在其名稱上使用愚蠢的字符串切片技巧。
變量名稱本身存儲在filter_expression.token
每個VariableNode
:
>>> varnodes[0].filter_expression.token
u'adjective'
所以一個簡單的列表理解會讓我們所有模板的變量名:
>>> template_vars = [x.filter_expression.token for x in varnodes]
>>> template_vars
[u'adjective', u'verb']
所以,不最簡單的解決方案,但如果有更好的方法我不知道它。
紅利:功能!
from django.template import VariableNode
def get_template_vars(t):
varnodes = t.nodelist.get_nodes_by_type(VariableNode)
return [x.filter_expression.token for x in varnodes]
好吧,它畢竟不是那麼複雜!
後續編輯:讓變量從父模板
(此後續使用從更新問題的信息)。
由於玩具模板的節點列表是一個單一的ExtendsNode
(在這種情況下),所以它確實變得複雜。
>>> toy.nodelist
[<ExtendsNode: extends "mysite/toyparent.html">]
我會想象在較大的模板中可能有多個ExtendsNode
對象。總之,如果你檢查ExtendsNode
,並從中提取父模板,你可以把父一樣我原來的例如:
>>> enode = toy.nodelist[0]
>>> enode.parent_name
u'mysite/toyparent.html'
>>> parent = enode.get_parent(enode.parent_name)
>>> parent
<django.template.Template object at 0x101c43790>
>>> parent.nodelist.get_nodes_by_type(VariableNode)
[<Variable Node: adjective>]
而且還有你的父模板提取adjective
變量。爲了執行鍼對ExtendsNode
一個測試,你可以從django.template.loader_tags
導入類:
>>> from django.template.loader_tags import ExtendsNode
>>> ext = toy.nodelist.get_nodes_by_type(ExtendsNode)
>>> ext
[<ExtendsNode: extends "mysite/toyparent.html">]
所以,你可以爲ExtendsNode
存在做對模板的一些測試,向後步行到父模板和單獨獲得這些變量名。但是,這看起來像是一堆蠕蟲。
例如,如果你做到這一點:
>>> toy.nodelist.get_nodes_by_type((ExtendsNode, VariableNode))
[<ExtendsNode: extends "mysite/toyparent.html">, <Variable Node: block.super>, <Variable Node: verb>]
現在你已經得到了ExtendsNode
和VariableNode
對象,它只是開始變得混亂。那我們做什麼?我們是否試圖忽略這些測試返回的任何block
變量?我不知道!!
無論如何,這是你想要的信息,但我不認爲這是一個實際的解決方案。我堅持認爲還是可能有更好的辦法。可能值得研究你想要解決的問題,看看你是否可以採取另一種方法。
謝謝 - 這很接近,但對於繼承似乎不能正常工作 - 請參閱上面的擴展問題描述。 – 2009-12-04 16:43:56
啊,你說得對。我甚至沒有考慮過模板擴展。讓我捅一下,看看我能否弄清楚。 – jathanism 2009-12-04 19:16:55
哇,很好的研究和信息。 +1 – 2009-12-05 05:13:47