2

我有一个仪表板,它为每个仪表板项的上下文命名。有没有一种快速的方法可以将字典的所有值设置为模板中的键?

我想重用模板,而不是总是命名我的变量。

我的上下文可以简化为如下所示:

{
 "business": {"businesses": [], "new_promotions": []}, 
 "messages": {"one_to_one": [], "announcements": []
}

因此,在 with 语句中,我想将所有业务项目设置为本地以包含在内。为此,目前我必须单独设置每个变量:

{% with %}
  {% set businesses = business["businesses"] %}
  {% set new_promotions = business["new_promotions"] %}
  {% include "businesses.html" %}
{% endwith %}

我试过了:

{% with %}
  {% for key, value in my_dict %}
    {% set key = value %}
  {% endfor %}
  {% include "businesses.html" %}
{% endwith %}

但是它们仅在 for 循环中具有作用域,因此在包含中没有作用域...

4

2 回答 2

4

长话短说:您不能在上下文中设置任意变量。这{% set key = value %}只是将命名的变量设置为key给定的值。

原因是 Jinja2 将模板编译成 Python 代码。(如果您想查看模板生成的代码,请在http://ryshcate.leafstorm.us/paste/71c95831ca0f1d5下载脚本并将模板的文件名传递给它。)为了加快处理速度,它为每个您在模板中使用的变量(仅在第一次遇到它时在上下文中查找变量),而不是 Django,它使用上下文进行所有变量查找。

为了正确生成此代码,它需要能够跟踪在任何给定时间存在哪些局部或全局变量,因此它知道何时在上下文中查找。并且设置随机变量会阻止它工作,这就是为什么contextfunction不允许 s 修改上下文,只需查看它。

不过,我要做的不是让您的业务显示代码成为包含的模板,而是让它成为另一个模板中的宏。例如,在businesses.html

{% macro show_businesses(businesses, new_promotions) %}
  {# whatever you're displaying... #}
{% endmacro %}

然后在你的主模板中:

{% from "businesses.html" import show_businesses %}
{% show_businesses(**businesses) %}

或者,更好的是,将它们分成两个单独的宏 - 一个用于企业,一个用于新促销。您可以在http://bitbucket.org/plurk/solace/src/tip/solace/templates/看到很多很酷的模板技巧,当然也可以在http://jinja.pocoo.org/2上查看 Jinja2 文档/文档/模板

于 2010-07-28T16:21:48.423 回答
1

我找到了一种解决方法——通过创建一个上下文函数,我可以渲染模板并直接设置上下文或合并上下文(虽然不确定这是一个好习惯)。

@jinja2.contextfunction
def render(context, template_name, extra_context, merge=False):
    template = jinja_env.get_template(template_name)

    # Merge or standalone context?
    if merge:
        ctx = context.items()
        ctx.update(extra_context)
    else:
        ctx = extra_context

    return jinja2.Markup(template.render(ctx))

所以我的模板看起来像:

{{ render("businesses.html", business) }}
于 2010-07-28T13:40:27.290 回答