在Django中在两个自定义标签之间传递变量

3 投票
1 回答
555 浏览
提问于 2025-04-16 12:32

我正在尝试实现一个 Django 模板标签 {% domready %}{% enddomready %},这个标签可以把它里面的内容保存起来,然后再用另一个标签 {% domready_render %} 来显示这些内容。

它的效果大概是这样的:

{# main.html #}
<html>
...
<body>
  ...
  <script>
      (function($) {
          $(document).ready(function() {
              {% domready_render %}
          });
      })(jQuery);
  </script>
</body>
</html>


{# some_other_file.html #}
{% extends main.html %}
..some html...
<a href="" id="link1">Link with onclick</a>
{% domready %}
    $('#link1').click(function() { ... describe here your javascript ... });
{% enddomready %}
..some html...
<a href="" id="link2">Another with onclick</a>
{% domready %}
    $('#link2').click(function() { ... describe here your another javascript ... });
{% enddomready %}
..some html...

所以我想问的是:我该怎么做呢?我试过这样:

@register.tag
def domready(parser, token):
    nodelist = parser.parse(('enddomready',))
    parser.delete_first_token()
    return DomreadyNode(nodelist)

class DomreadyNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist

    def render(self, context):
        if 'dom_ready' not in context:
            context['dom_ready'] = []

        context['dom_ready'].append(self.nodelist.render(context))
        return ''

@register.tag
def domready_render(parser, token):
    return DomreadyRenderNode()

class DomreadyRenderNode(template.Node):
    def render(self, context):
        if 'dom_ready' in context:
            return u"\n".join(context['dom_ready'])
        return ''

但是这个 context['dom_ready'] 只在同一个模板中有效(也就是说,我可以在 some_other_file.html 中使用 {{ dom_ready }},但在 main.html 中看不到它,可能是因为它们的渲染上下文不同之类的原因?

谢谢。

1 个回答

2

正如你所猜的,渲染上下文在不同的模板文件之间是不会共享的。

你可以通过使用一个模块级别的变量来解决这个问题,这个变量是在你定义模板标签的地方。

只需在文件的顶部添加

dom_ready = []

然后在你使用 context['dom_ready'] 的地方,把它替换成 dom_ready。

你知道吗?其实你可以多次调用 $.ready,这样可能会比用模板标签来实现更简单、更干净。

撰写回答