我想創建一個自定義模板標記,只渲染一段代碼,無論包含它的標記/部分執行多少次。Django做一次自定義模板標記
這是怎麼了,我實現它,但是你可以看到,這是一個有點hackish:
my_partial.html:
{% once mycontent %}
this will only show once
{% endonce%}
my_template.html:
{% load my_tags %}
{% for i in list %}
{% my_partial %}
{% endfor %}
my_tags.py:
@register.inclusion_tag('my_partial.html',takes_context=True)
def my_partial(context):
return dict(arbitrary extra data)
@register.tag(name="once")
def do_once(parser, token):
try:
# Splitting by None == splitting by spaces.
tag_name, var_name = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError("%r tag requires arguments" % token.contents.split()[0])
nodelist = parser.parse(('endonce',))
parser.delete_first_token()
return DoOnceNode(nodelist, var_name)
class DoOnceNode(template.Node):
def __init__(self, nodelist, var_name):
self.nodelist = nodelist
self.var_name = '_do_once_'+var_name
def render(self, context):
request = context['request']
# Make request.GET mutable.
request.GET = dict(request.GET)
if self.var_name in request.GET:
return ''
else:
request.GET[self.var_name] = 1
return self.nodelist.render(context)
具體來說,我使用request.GET字典作爲可變全局範圍。這很破爛,顯然不是請求對象設計的目的,但它起作用。
理想情況下,我想使用類似上下文的東西,但我發現它不會在對此標記的調用之間共享。即self.var_name in context
總是False,使其作爲全局範圍無用。
爲什麼不共享上下文以共享請求的方式?有沒有辦法讓它真正共享,還是有一些其他對象可以用來在請求中存儲全局可訪問的變量?
怎麼樣的request.session?這是一個少一點hackish。 「一次」模板標籤有什麼用途? – Tiago
我沒有使用會話,因爲它不想保存超出請求的任何內容。如果我在會話中保存元數據,將會在請求之外使用無意義的數據污染我的數據庫。我的使用案例是爲通常隱藏的模式對話框添加HTML,並且可能會使用多個可選的小部件,這些小部件可能會或可能不會在頁面上使用。我希望每個小部件都包含部分內容,但只做一次,以避免與存在於不同位置的相同ID發生衝突。 – Cerin