【问题标题】:Django - how to get the contents of a {% block %} tag from a templateDjango - 如何从模板中获取 {% block %} 标签的内容
【发布时间】:2011-12-07 04:34:27
【问题描述】:

我已经走到这一步了:

>>> some_template = get_template_from_string(
...     load_template_source(
...         'some_template.html',
...         settings.TEMPLATE_DIRS))
... 
>>> blocks = some_template.nodelist.get_nodes_by_type(BlockNode)
>>> blocks[0]
<Block Node: another_block. Contents: [<Text Node: '\nThis one is really cool'>, <Block Node: sub_block. Contents: [<Text Node: '\nI\'m a sub-block.\n\t'>]>, <Text Node: '\n'>]>
>>> # Right there is when I realized this wasn't going to be fun.

您看,块的内容包含在block.nodelist 中,而不仅仅是纯文本。如果我有模板:

{% extends "base.html" %}

{% block some_block %}
Some value
{% endblock %}

{% block other_block %}
Other Value
    {% sub_block %}Sub block value{% endblock %}
{% endblock %}

我希望能够做到这一点:

>>> get_block_source('other_block')
'\nOther Value\n    {% sub_block %}Sub block value{% endblock %}\n'
>>> get_block_source('sub_block')
'Sub block value'

如果 Django 的内部没有提供足够的资源来找到一种方法来做到这一点,我也可以使用正则表达式/一系列正则表达式,但我看不出单独使用正则表达式是如何实现的,假设您可以嵌套{% block... 标签。

【问题讨论】:

  • 我们这样做是因为通常有更好的方法。许多开发人员决定了一个解决方案,然后半途而废,陷入困境,然后只是问如何解决他们面前的问题,而不是问如何解决最初的问题。
  • @orokusaki:啊,你可能误解了他(或者没有,很难说)。请注意,如果您从字面上阅读他的问题,他只是在向您询问有关更大问题的更多信息:“您为什么要这样做?”但在文化上,我们习惯于将这个问题简单地解释为“你错了”。这是使用这类在线论坛的一大挑战。

标签: python regex django django-templates


【解决方案1】:

这似乎是你在努力对抗 Django 颗粒。将内容放入包含文件中,然后将{% include %} 放入您的块中,也可以直接读取该文件。如果你能告诉我们更多关于你想要完成的事情,可能有更好的方法来做到这一点。

【讨论】:

    【解决方案2】:

    我创建的解决方案:

    import re
    
    
    BLOCK_RE = re.compile(r'{%\s*block\s*(\w+)\s*%}')
    NAMED_BLOCK_RE = r'{%%\s*block\s*%s\s*%%}'  # Accepts string formatting
    ENDBLOCK_RE = re.compile(r'{%\s*endblock\s*(?:\w+\s*)?%}')
    
    
    def get_block_source(template_source, block_name):
        """
        Given a template's source code, and the name of a defined block tag,
        returns the source inside the block tag.
        """
        # Find the open block for the given name
        match = re.search(NAMED_BLOCK_RE % (block_name,), template_source)
        if match is None:
            raise ValueError(u'Template block {n} not found'.format(n=block_name))
        end = inner_start = start = match.end()
        end_width = 0
        while True:
            # Set ``end`` current end to just out side the previous end block
            end += end_width
            # Find the next end block
            match = re.search(ENDBLOCK_RE, template_source[end:])
            # Set ``end`` to just inside the next end block
            end += match.start()
            # Get the width of the end block, in case of another iteration
            end_width = match.end() - match.start()
            # Search for any open blocks between any previously found open blocks,
            # and the current ``end``
            nested = re.search(BLOCK_RE, template_source[inner_start:end])
            if nested is None:
                # Nothing found, so we have the correct end block
                break
            else:
                # Nested open block found, so set our nested search cursor to just
                # past the inner open block that was found, and continue iteration
                inner_start += nested.end()
        # Return the value between our ``start`` and final ``end`` locations
        return template_source[start:end]
    

    【讨论】:

      猜你喜欢
      • 2016-04-21
      • 2017-02-16
      • 1970-01-01
      • 2014-07-25
      • 2016-06-28
      • 2019-06-15
      • 1970-01-01
      • 2013-11-08
      • 2012-01-04
      相关资源
      最近更新 更多