Django:我如何从模板中获取块?

时间:2010-04-21 23:09:46

标签: python django django-templates

假设我的模板中包含类似{% block subject %}my subject{% endblock %}的内容,并使用tmpl = loader.get_template('mytemplate.html')加载此模板,如何提取“我的主题”?

4 个答案:

答案 0 :(得分:6)

当您的模板扩展基础时,Camilo的解决方案不起作用。我已经修改了一下(希望)解决了这个问题:

from django.template import Context
from django.template.loader import get_template
from django.template.loader_tags import BlockNode, ExtendsNode

def _get_node(template, context=Context(), name='subject'):
    for node in template:
        if isinstance(node, BlockNode) and node.name == name:
            return node.render(context)
        elif isinstance(node, ExtendsNode):
            return _get_node(node.nodelist, context, name)
    raise Exception("Node '%s' could not be found in template." % name)

我真的不确定这是否是以递归方式迭代所有节点的正确方法......但它在我的有限情况下有效。

答案 1 :(得分:5)

from django.template import Context
from django.template.loader import get_template
from django.template.loader_tags import BlockNode

t = get_template('template.html')
for node in t:
    if isinstance(node, BlockNode) and node.name == 'subject':
        print node.render(Context())

这对我有用,使用Django 1.1.1

答案 2 :(得分:5)

Django 1.8以来,建议的答案无效:

  

在Django 1.8中更改:get_template()返回依赖于后端的   模板而不是django.template.Template。

新的django.template.backends.django.Template不可迭代,因此for循环会出错:

  

'模板'对象不可迭代。

使用Django模板系统的解决方案(基于@CamiloDíazRepka答案):

from django.template import Context
from django.template.loader import get_template
from django.template.loader_tags import BlockNode

t = get_template('template.html')
for node in t.template:
    if isinstance(node, BlockNode) and node.name == 'subject':
        print node.render(Context())

答案 3 :(得分:3)

我希望这可以创建一个只包含相关模板部分的include标记。我在这里分享它,以防其他人因为同样的原因而想要它。

用法:{%include_block“template.html”“block_name”%}

@register.tag
def include_block(parser, token):
    try:
        tag_name, include_file, block_name = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError("%r tag requires a two arguments" % (token.contents.split()[0]))

    #pass vars with stripped quotes 
    return IncludeBlockNode(include_file.replace('"', ''), block_name.replace('"', ''))

class IncludeBlockNode(template.Node):
    def __init__(self, include_file, block_name):
        self.include_file = include_file
        self.block_name = block_name

    def _get_node(self, template, context, name):
        '''
        taken originally from
        http://stackoverflow.com/questions/2687173/django-how-can-i-get-a-block-from-a-template
        '''
        for node in template:
            if isinstance(node, BlockNode) and node.name == name:
                return node.nodelist.render(context)
            elif isinstance(node, ExtendsNode):
                return self._get_node(node.nodelist, context, name)

        raise Exception("Node '%s' could not be found in template." % name)

    def render(self, context):
        t = get_template(self.include_file)
        return self._get_node(t, context, self.block_name)