Я пытаюсь создать пользовательский тег шаблона, который отображает блок кода только один раз, независимо от того, сколько раз тег / фрагмент, содержащий его, выполняется.
Вот как я реализовалэто, но, как вы можете видеть, это немного хакерски:
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
всегда ложно, что делает его бесполезным в качестве глобальной области.
Почему контекст не передается так же, как и запрос?Есть ли какой-то способ сделать его действительно общим или есть какой-то другой объект, который я могу использовать для хранения глобально доступных переменных внутри запроса?