Django模板的上下文变量范围?

时间:2022-05-23 06:46:49

I'm looking for a solution how to "shadow" context variables in a Django's template.

我正在寻找一个解决方案如何在Django的模板中“遮蔽”上下文变量。

Let's have the following structure in one of templates:

让我们在其中一个模板中使用以下结构:

{% block content %}
  {# set context variables with a custom tag #}
  {% paginator_ctx products %}  {# sets `paginator' in context dict #}
  {% for product in paginator.object_list %}
    {# Render elements from _outer_ loop #}
    {% paginator_ctx child_products %} {# !! replaces context !! #}
    {% for cat in paginator.object_list %}
      {# Render elements from _inner_ loop #}
    {% endfor %}
    {% include "paginator.html" %}
  {% endfor %}
  {# ?? how to restore the original context ?? #}
  {% include "paginator.html" %}  {# renders prev, next & current page number #}
{% endblock %}

I hope it's obvious from the example what I'd need to achieve. To have local scope in a template similar how it does work in Python. Or am I taking it from a wrong side ? To have generic templates relying on context variables instead of passing values in arguments ?

我希望从示例中可以看出我需要实现的目标。使模板中的本地范围类似于它在Python中的工作方式。或者我是从错误的一方拿走它?要使通用模板依赖于上下文变量而不是在参数中传递值?

Thanks.

Update: There is some a bit hackish solution to manually store context variables:

更新:有一些手动存储上下文变量的hackish解决方案:

{# outer block #}
  {% with context_var as context_var_saved %}
    {# inner/nested block overwriting context_var #}
    {% with context_var_saved as context_var %}
      {# process restored context_var #}
    {% endwith %}
    {# end of inner block #}
  {% endwith %}
{# end of outer block #}

No cleaner solution available ? What if I'd need to store more variables or the whole context ?

没有清洁解决方案?如果我需要存储更多变量或整个上下文怎么办?

1 个解决方案

#1


1  

Having a similar issue, I decided to create a global_scope block in my base_site.html template that wraps everything and to use it exclusively to assign "multiple blocks" context variables.

遇到类似的问题,我决定在我的base_site.html模板中创建一个global_scope块,它包装所有内容并专门用它来分配“多个块”上下文变量。

It goes like this:

它是这样的:

>> base_site.html

{% block global_scope %}
<!DOCTYPE html>
<html>
    ...
    <more blocks here>
</html>
{% endblock global_scope %}

Then in a specialized template:

然后在专门的模板中:

{% block global_scope %}
    {# set context variables with a custom tag #}
    {{ block.super }} {# <-- important! #}
{% endblock global_scope %}

{% block content %}
    {# the context variable is available here #}
{% endblock %}

With this approach, though, you have to double check that you are not overriding any variables that someone else set in the template hierarchy.

但是,通过这种方法,您必须仔细检查是否未覆盖其他人在模板层次结构中设置的任何变量。

Furthermore, depending on the size of your variable, maybe there is a memory overhead, being that the variable won't be popped out of the context until the very end of the template.

此外,根据变量的大小,可能存在内存开销,因为在模板的最后,变量不会从上下文中弹出。

#1


1  

Having a similar issue, I decided to create a global_scope block in my base_site.html template that wraps everything and to use it exclusively to assign "multiple blocks" context variables.

遇到类似的问题,我决定在我的base_site.html模板中创建一个global_scope块,它包装所有内容并专门用它来分配“多个块”上下文变量。

It goes like this:

它是这样的:

>> base_site.html

{% block global_scope %}
<!DOCTYPE html>
<html>
    ...
    <more blocks here>
</html>
{% endblock global_scope %}

Then in a specialized template:

然后在专门的模板中:

{% block global_scope %}
    {# set context variables with a custom tag #}
    {{ block.super }} {# <-- important! #}
{% endblock global_scope %}

{% block content %}
    {# the context variable is available here #}
{% endblock %}

With this approach, though, you have to double check that you are not overriding any variables that someone else set in the template hierarchy.

但是,通过这种方法,您必须仔细检查是否未覆盖其他人在模板层次结构中设置的任何变量。

Furthermore, depending on the size of your variable, maybe there is a memory overhead, being that the variable won't be popped out of the context until the very end of the template.

此外,根据变量的大小,可能存在内存开销,因为在模板的最后,变量不会从上下文中弹出。