另一种常见类型的模板标记是通过呈现另一个模板来显示某些数据的类型。例如,Django的管理界面使用自定义模板标签显示“添加/更改”表单页面底部的按钮。这些按钮看起来总是一样,但链接目标会根据正在编辑的对象而改变 - 因此它们是使用填充了当前对象详细信息的小模板的完美案例。(在管理员的情况下,这是submit_row
标签。)
这些类型的标签称为“包含标签”。
编写包含标签可能最好通过示例来说明。让我们编写一个标记,输出给定Poll
对象的选项列表,例如在教程中创建的。我们将使用这样的标签:
{% show_results poll %}
...输出将是这样的:
<ul>
<li>First choice</li>
<li>Second choice</li>
<li>Third choice</li>
</ul>
首先,定义接受参数的函数并为结果生成数据字典。这里重点是我们只需要返回字典,而不是更复杂的字典。这将用作模板片段的模板上下文。例:
def show_results(poll):
choices = poll.choice_set.all()
return {'choices': choices}
接下来,创建用于呈现标记输出的模板。此模板是标记的固定功能:标记编写器指定它,而不是模板设计器。按照我们的示例,模板非常简单:
<ul>
{% for choice in choices %}
<li> {{ choice }} </li>
{% endfor %}
</ul>
现在,通过调用对象inclusion_tag()
上的方法来创建和注册包含标记Library
。按照我们的示例,如果上面的模板位于results.html
由模板加载器搜索的目录中调用的文件中,我们将注册标记,如下所示:
# Here, register is a django.template.Library instance, as before
@register.inclusion_tag('results.html')
def show_results(poll):
...
或者,可以使用django.template.Template
实例注册包含标记 :
from django.template.loader import get_template
t = get_template('results.html')
register.inclusion_tag(t)(show_results)
......首次创建功能时
有时,包含标记可能需要大量参数,这使得模板作者难以传递所有参数并记住它们的顺序。为了解决这个问题,Django takes_context
为包含标记提供了一个选项。如果takes_context
在创建模板标记时指定,则标记将没有必需的参数,并且基础Python函数将具有一个参数 - 从调用标记时开始的模板上下文。
例如,假设你正在写,将永远在包含上下文中使用一个包含标签home_link
和home_title
指向回主页变量。这是Python函数的样子:
@register.inclusion_tag('link.html', takes_context=True)
def jump_link(context):
return {
'link': context['home_link'],
'title': context['home_title'],
}
请注意,必须调用函数的第一个参数context
。
在该register.inclusion_tag()
行中,我们指定takes_context=True
了模板的名称。这是模板的link.html
外观:
Jump directly to <a href="{{ link }}">{{ title }}</a>.
然后,只要你想使用那个自定义标签,加载它的库并在没有任何参数的情况下调用它,如下所示:
{% jump_link %}
请注意,在使用时takes_context=True
,无需将参数传递给模板标记。它会自动访问上下文。
该takes_context
参数默认为False
。当它设置为时 True
,标记将传递给上下文对象,如本例所示。这是本案与前一个案例的唯一区别inclusion_tag
。
inclusion_tag
函数可以接受任意数量的位置或关键字参数。例如:
@register.inclusion_tag('my_template.html')
def my_tag(a, b, *args, **kwargs):
warning = kwargs['warning']
profile = kwargs['profile']
...
return ...
然后在模板中,可以将由空格分隔的任意数量的参数传递给模板标记。与在Python中一样,关键字参数的值使用等号(“ =
”)设置,并且必须在位置参数之后提供。例如:
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}