Como gerar uma lista delimitada por vírgula no modelo python jinja?

179

Se eu tiver uma lista , usersdigamos ["Sam", "Bob", "Joe"], quero fazer algo em que possa produzir no meu arquivo de modelo jinja:

{% for user in userlist %}
    <a href="/profile/{{ user }}/">{{ user }}</a>
    {% if !loop.last %}
        , 
    {% endif %}
{% endfor %}   

Eu quero fazer o modelo de saída ser:

Sam, Bob, Joe

Eu tentei o código acima para verificar se estava na última iteração do loop e, se não, não insira uma vírgula, mas não funciona. Como eu faço isso?

Rolando
fonte
jinja, como Python, não usa !como operador de negação. "not" está escrito "not".
Wooble 15/08/12

Respostas:

306

Você deseja que seu ifcheque seja:

{% if not loop.last %}
    ,
{% endif %}

Observe que você também pode reduzir o código usando If Expression :

{{ "," if not loop.last }}
Joe Day
fonte
2
Isto é incrível, especialmente no final do loop em html
Sinux
7
Apenas para sua informação, pode ser necessário torná-lo um if / else com base nas suas configurações. Mais informações. pode ser encontrado aqui: github.com/pallets/jinja/issues/710
Paul Calabro
1
ou é alguns casos{{ "," if not forloop.last }}
obotezat
5
Eu segundo o comentário sobre a adição de um outro. Isso funcionou para mim{{ "," if not loop.last else "" }}
ahong 05/07/19
197

você também pode usar o filtro "join" incorporado ( http://jinja.pocoo.org/docs/templates/#join assim:

{{ users|join(', ') }}
Uli Martens
fonte
1
Enquanto isso funciona para criar um csv, vendo seu exemplo acima, ele não pode ser usado com a âncora ao redor.
Triunenature
Essa abordagem também não funciona bem com o escape: ['{{[' a \ '', 'b'] | join ("','")}} '] produz [' a & # 39; & # 39; , & # 39; b ']
stewbasic 24/11/2015
6
Esta deve ser a primeira coisa tentada. Se não funcionar como desejado, tente outra solução, mas isso é definitivamente mais limpo.
Jerad
Isso dá uma vírgula à direita, como faço para me livrar disso?
11137 Jonathan
Você provavelmente tem um elemento vazio à direita. Se você tem três elementos abc você receberá AxBxC quando se associar com X:ansible -i localhost, all -m debug -a "msg=\"{{ [ 'a','b','c' ]|join('X') }}\""
Uli Martens
61

E usando a joinerpartir http://jinja.pocoo.org/docs/dev/templates/#joiner

{% set comma = joiner(",") %}
{% for user in userlist %}
    {{ comma() }}<a href="/profile/{{ user }}/">{{ user }}</a>
{% endfor %}  

É feito para esse propósito exato. Normalmente, uma junção ou uma verificação de forloop.last seria suficiente para uma única lista, mas para vários grupos de coisas é útil.

Um exemplo mais complexo sobre por que você o usaria.

{% set pipe = joiner("|") %}
{% if categories %} {{ pipe() }}
    Categories: {{ categories|join(", ") }}
{% endif %}
{% if author %} {{ pipe() }}
    Author: {{ author() }}
{% endif %}
{% if can_edit %} {{ pipe() }}
    <a href="?action=edit">Edit</a>
{% endif %}
dalore
fonte
1
Isso realmente funcionou muito bem para mim, sem deixar uma vírgula à direita. Obrigado por este!
Daniel Andrei Mincă
7

O código a seguir funcionou usando o filtro de junção jinja2 que Uli Martens sugeriu no shell python3.5:

>>> users = ["Sam", "Bob", "Joe"]
>>> from jinja2 import Template
>>> template = Template("{{ users|join(', ') }}")
>>> template.render(users=users)
'Sam, Bob, Joe'
rok
fonte