私は、それを含むタグ/部分が何回実行されているかにかかわらず、一度に1ブロックのコードしかレンダリングしないカスタムテンプレートタグを作成しようとしています。Django Do Onceカスタムテンプレートタグ
これは私がそれを実現してきた方法ですが、あなたが見ることができるように、それは少しハックです:
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について?ちょっとハッキリしていません。 'once'テンプレートタグのユースケースは何ですか? – Tiago
リクエストを超えて何も保存しないので、私はセッションを使用しませんでした。セッションにメタデータを保存すると、要求の範囲外で意味のないデータでデータベースが汚染されます。私の使用例は、通常は隠されているモーダルダイアログのHTMLをインクルードすることです。これは、ページ上で使用されるかもしれないし、使用されないかもしれないいくつかのオプションのウィジェットによって使用されるかもしれません。私は、各ウィジェットに部分的なものを含めることを望みますが、異なる場所に存在する同じIDとの競合を避けるために、一度だけ行います。 – Cerin