【问题标题】:Variable context between two blocks in Django templates?Django模板中两个块之间的变量上下文?
【发布时间】:2018-07-16 12:52:40
【问题描述】:

我有两个块使用相同的变量调用相同的方法。我只想调用一次该方法,但结果超出了块标记的范围。我尝试在父模板header.htmlwith 标记中调用此方法,但似乎没有任何效果。

这是布局:

{% 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

【问题讨论】:

  • get_section 的代码也包含在内可能是个好主意....此外,如果它不是一个昂贵的电话,那么做两次可能会更容易
  • @ResleyRodrigues 问题已更新。
  • 会不会是因为你在if 条件下没有返回任何东西?
  • @ResleyRodrigues 很好地指出,忘记了。然而,这不是问题。返回值仍然超出范围。
  • 既然是同一个模板,你不能在视图注入的上下文中包含section信息吗?

标签: python django templates


【解决方案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 backport django.utils.lru_cache.lru_cache

@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

【讨论】:

  • 谢谢。我知道我可以在视图的上下文中设置它,但我想知道我是否可以在模板级别上做些什么。这工作正常。
  • 明白。 Django 的模板被设计成限制了他们能做的事情,所以我发现解决方案通常是在他们之外寻找。
【解决方案2】:

我不会在 .py 之外调用方法。认为这是使用 Jinja2 模板, 它很强大,但不像后端那样。

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

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

context['site_parent'] = get_parent_section(site)

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

如果您愿意,可以阅读官方 django 网站关于模板https://docs.djangoproject.com/en/2.0/topics/templates/

但根据我的经验,我会将方法调用保留在 views.py 中

【讨论】:

    猜你喜欢
    • 2016-06-20
    • 1970-01-01
    • 2017-01-29
    • 2013-09-18
    • 2017-03-10
    • 2018-12-28
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多