【发布时间】:2011-10-05 12:59:27
【问题描述】:
我正在尝试创建一个自定义模板标记,该标记只呈现一次代码块,而不管包含它的标记/部分执行多少次。
这就是我实现它的方式,但正如您所见,它有点 hackish:
my_partial.html:
{% once mycontent %}
this will only show once
{% endonce%}
我的模板.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 呢?它不那么骇人听闻。 'once' 模板标签的用例是什么?
-
我没有使用会话,因为它不想保存超出请求的任何内容。如果我在会话中保存元数据,它将用在请求之外无意义的数据污染我的数据库。我的用例是包含一个模态对话框的 HTML,它通常是隐藏的,并且可以由几个可选的小部件使用,这些小部件可能会或可能不会在页面上使用。我希望每个小部件都包含部分内容,但只执行一次以避免与存在于不同位置的相同 ID 发生冲突。
标签: python django django-templates