Variável de modelo Jinja2 se Nenhum Objeto definir um valor padrão

146

Como tornar uma variável no jijna2 padrão para "" se o objeto for None em vez de fazer algo parecido com isto?

      {% if p %}   
        {{ p.User['first_name']}}
      {% else %}
        NONE
      {%endif %}

Portanto, se o objeto p for None, eu quero padronizar os valores de p (first_name e last_name) para "". Basicamente

nvl(p.User[first_name'], "")

Erro ao receber:

Error:  jinja2.exceptions.UndefinedError
    UndefinedError: 'None' has no attribute 'User'
mcd
fonte
1
Faça a função que retornou o valor de pnunca retornar None. Em vez da Nonefunção, retorne um objeto proxy que tenha a mesma estrutura que um objeto real, mas seja carregado com os valores padrão que você deseja.
Miguel
Eu uso isso e meu problema foi resolvido: {% if p! = None%} {{p.User ['first_name']}} {% endif%} #
Mona Mohamadinia

Respostas:

242

Use a nonefunção incorporada ( http://jinja.pocoo.org/docs/templates/#none ):

{% if p is not none %}   
    {{ p.User['first_name'] }}
{% else %}
    NONE
{%endif %}

ou

{{ p.User['first_name'] if p != None else 'NONE' }}

ou se você precisar de uma string vazia:

{{ p.User['first_name'] if p != None }}
tbicr
fonte
19
Observe a minúscula nonena resposta. Meu problema foi resolvido depois que eu corrigi o caso de None.
harperville
127
{{p.User['first_name'] or 'My default string'}}
Torindo
fonte
70

De acordo com os documentos, você pode fazer:

{{ p|default('', true) }}

A causa é Noneconvertida Falseem contexto booleano.


Atualização : Como os lindes mencionaram, ele funciona apenas para tipos de dados simples.

mitenka
fonte
5
Isso funciona para uma variável simples, mas não para esta pergunta em que você deseja obter um campo de um campo mais complexo. Eu votaria contra isso, já que não é uma boa resposta para a pergunta original ... e, ao mesmo tempo, saber defaultexatamente o que eu precisava para o meu caso em particular, então ... simplesmente não votar. (Uma edição para esta resposta pode muito bem ganhar-lhe um upvote, exceto que eu acho que é provavelmente difícil aplicar defaulta esta situação)
lindes
31

Como complemento a outras respostas, pode-se escrever outra coisa se a variável for None como este:

{{ variable or '' }}
Ivan Bryzzhin
fonte
3
Estou impressionado com essa simplicidade! Python x or yé if x is false, then y, else x. Veja: 5.2. Operações booleanas - e, ou, não
kenjiuno
10

Após este documento, você pode fazer o seguinte:

{{ p.User['first_name']|default('NONE') }}
pawel7318
fonte
8
Acho que não - o filtro de modelo "padrão" retorna o valor padrão se o valor estiver indefinido / ausente.
Codeape 14/10
Trabalhou para mim ao usar o ansible. Isso tornou mais clara: stackoverflow.com/q/28885184/1005215
Nehalem J Wani
1
Se p estiver definido. Mas se P não está definido que não funciona
dalore
5

Para evitar lançar uma exceção enquanto "p" ou "p.Usuário" é Nenhum, você pode usar:

{{ (p and p.User and p.User['first_name']) or "default_value" }}
Sub
fonte
4
Este é o único que funcionou para mim, pois minha variável foi enterrada profundamente em um ditado.
Craicerjack
Isso ajuda a limpar alguns outros com muita lógica.
eagle33322
1

Como outra solução (semelhante a algumas anteriores):

{{ ( p is defined and p.User is defined and p.User['first_name'] ) |default("NONE", True) }}

Observe que a última variável (p.User ['first_name']) não possui o if definedteste após ela.

Apollo
fonte
0

Normalmente, defino uma nvlfunção e a coloco em globalse filters.

def nvl(*args):
    for item in args:
        if item is not None:
            return item
    return None

app.jinja_env.globals['nvl'] = nvl
app.jinja_env.filters['nvl'] = nvl

Uso em um modelo:

<span>Welcome {{ nvl(person.nick, person.name, 'Anonymous') }}<span>

// or 

<span>Welcome {{ person.nick | nvl(person.name, 'Anonymous') }}<span>
Tamas Hegedus
fonte