Django模板中两个块之间的可变上下文?

时间:2018-07-16 12:52:41

标签: python django templates

我有两个用相同变量调用相同方法的块。我只想调用该方法一次,但是结果却超出了块标记的范围。我尝试在父模板header.html中使用with标签调用此方法,但似乎无济于事。

这是布局:

{% extends "header.html" %}

{% load navigation_tags %}

{% block header %}
    {% get_section site=site as section %}
    {% include "foobar.html" with section=section %}
{% endblock header %}

{% block navigation %}
    <nav>
        <div class="container">
            {% get_section site=site as section %}
            {% navigation section.slug %}
        </div>
    </nav>
{% endblock navigation %}

navigation_tags.py

@register.assignment_tag
def get_parent_section(site):
    if site.id == settings.FOOBAR_SITE_ID:
        section = Section.objects.get(id=settings.FOOBAR_SECTION_ID)
    else:
        # This is also a section instance.
        return site.default_section

2 个答案:

答案 0 :(得分:1)

正如2pacho在另一个答案中和Fernando Cezar在评论中所提到的,在不同部分之间共享值的最简单方法是在模板上下文中进行设置。如果您使用render快捷功能,则可以将dict作为 context 参数传递,以将值添加到模板的呈现上下文。那将是添加它的好地方,并且这将是放置它的最简单的地方。

return render(request, 'template.html', {'section': get_parent_section(site)})

但是,如果由于某种原因而不能将其包含在上下文中,则可以使用装饰器将memoization添加到函数中,以便它将缓存计算结果并在调用时立即返回具有相同的参数。您可以使用functools.lru_cache进行操作,如果您使用的是Python 2.x,则可以使用django.utils.lru_cache.lru_cache上的Django backport。

@register.assignment_tag
@functools.lru_cache()
def get_parent_section(site):
    if site.id == settings.FOOBAR_SITE_ID:
        section = Section.objects.get(id=settings.FOOBAR_SECTION_ID)
    else:
        # This is also a section instance.
        return site.default_section

答案 1 :(得分:0)

我不会在.py之外调用方法。认为这是使用Jinja2模板, 它功能强大,但后端却无法实现。

在这种情况下,我建议您为模板生成一个上下文并在其中使用此变量。

就像将它添加到生成它的上下文中一样简单。

context['site_parent'] = get_parent_section(site)

认为Jinja2(html)必须尽可能简单,并且可以帮助您进行基本编码和节省时间(例如循环以打印完全相同的信息或根据上下文显示和隐藏代码),但我会保持渲染时非常简单。

如果您希望阅读有关模板https://docs.djangoproject.com/en/2.0/topics/templates/的django官方网站

但是从我的经验来看,我会将方法调用保留在views.py