如何使用Jinja for循环连接字符串?

7
我想通过一个“for”循环迭代地连接字符串以构建URL参数,但我认为我存在作用域问题。
The output should be: url_param = "&query_param=hello&query_param=world"

array_of_objects = [{'id':'hello'},{'id':'world'}]

{% set url_param = "" %}

{% set array_of_ids = array_of_objects|map(attribute='id')|list%} // correctly returns [1,2]

{% for id in array_of_ids %}
   {% set param = '&query_param='~id %}
   {% set url_param = url_param~param %}                             
{% endfor %}

//url_param is still an empty string

我也尝试过使用namespace(),但无济于事:
{% set ns = namespace() %}
 {% set ns.output = '' %}
 {% set array_of_ids = array_of_objects|map(attribute='id')|list%} // correctly returns [1,2]
{% for id in array_of_ids %}
   {% set param = '&industries='~id%}
   {% set ns.output = ns.output~param %}                             
{% endfor %}
//ns.output returns namespace
2个回答

9

这确实是一个作用域问题。解决此问题的一种“hacky”方式是使用一个列表,然后像下面这样添加:

{% set array_of_objects = [{'id':'hello'},{'id':'world'}] %}

{% set array_of_ids = array_of_objects|map(attribute='id')|list%}

{{ array_of_ids|pprint }} {# output: ['hello', 'world'] #}

{% set ids = [] %}  {# Temporary list #}

{% for id in array_of_ids %}
   {% set param = '&query_param='~id %}
   {% set url_param = url_param~param %}
   {{ ids.append(url_param) }}
{% endfor %}

{{ ids|pprint }} {# output: [u'&query_param=hello', u'&query_param=world'] #}
{{ ids|join|pprint }} {# output: "&query_param=hello&query_param=world" #}

上面的代码可以满足你的需求,但是对于这个特定的例子,我建议使用jinja的join过滤器。它更加声明式,感觉不那么hacky。

{% set array_of_objects = [{'id':'hello'},{'id':'world'}] %}

{# set to a variable #}
{% set query_string = "&query_param=" ~ array_of_objects|join("&query_param=", attribute="id") %}

{{ query_string|pprint }}
{# output: u'&query_param=hello&query_param=world'  #}

{# or just use it inline #}
{{ "&query_param=" ~ array_of_objects|join("&query_param=", attribute="id") }}

1
谢谢,Dylan!你的第二个解决方案非常好用!我不知道join可以接受多个参数。第一个解决方案在没有{% set url_param = url_param~param %}的情况下也可以工作,但我确定那是一个笔误。我实际上尝试了类似的解决方案,但认为在附加数组时必须调用“do”。 - Brandi

1
你需要更改命名空间的初始化。这里是来自docs的示例,可以帮助你解决问题:
{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}

在我看来,这是最好的答案。没有任何黑科技,只需使用语言特性。@Brandi:你在第二个解决方案中所需要做的就是将“ns”设置为“namespace(output)”。 - MastroGeppetto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接