Zmienna szablonu Jinja2, jeśli żaden obiekt nie ustawił wartości domyślnej

146

Jak ustawić zmienną w jijna2 jako domyślną, jeśli obiekt ma wartość None zamiast robić coś takiego?

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

Więc jeśli obiekt p ma wartość None, chcę ustawić domyślne wartości p (first_name i last_name) na „”. Gruntownie

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

Błąd podczas odbierania:

Error:  jinja2.exceptions.UndefinedError
    UndefinedError: 'None' has no attribute 'User'
mcd
źródło
1
Spraw, aby funkcja, która zwróciła wartość pnigdy nie zwraca None. Zamiast Nonefunkcji powinna zwrócić obiekt proxy, który ma taką samą strukturę jak rzeczywisty obiekt, ale jest ładowany z domyślnymi wartościami, które chcesz.
Miguel
Używam tego i mój problem został rozwiązany: {% if p! = None%} {{p.User ['first_name']}} {% endif%}
Mona Mohamadinia,

Odpowiedzi:

242

Skorzystaj z nonewbudowanej funkcji ( http://jinja.pocoo.org/docs/templates/#none ):

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

lub

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

lub jeśli potrzebujesz pustego ciągu:

{{ p.User['first_name'] if p != None }}
tbicr
źródło
19
Zwróć uwagę na małą literę nonew odpowiedzi. Mój problem został rozwiązany po tym, jak poprawiłem przypadek Żaden.
harperville
127
{{p.User['first_name'] or 'My default string'}}
Torindo
źródło
70

Według dokumentów możesz po prostu zrobić:

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

Powoduj Nonerzutowanie na Falsew kontekście logicznym.


Aktualizacja : Jak wspomniałem Lindes, działa tylko dla prostych typów danych.

mitenka
źródło
5
Działa to w przypadku prostej zmiennej, ale nie w przypadku tego pytania, w którym chcesz pobrać pole z bardziej złożonego. Głosowałbym negatywnie, ponieważ nie jest to dobra odpowiedź na pierwotne pytanie ... a jednocześnie wiedza o tym defaultjest dokładnie tym, czego potrzebowałem w moim konkretnym przypadku, więc ... po prostu nie głosuję. (Zmiana tej odpowiedzi może przynieść jej pozytywną opinię, z wyjątkiem tego, że myślę, że prawdopodobnie trudno ją zastosować defaultw tej sytuacji)
Lindes
31

Oprócz innych odpowiedzi można napisać coś innego, jeśli zmienna ma wartość None w ten sposób:

{{ variable or '' }}
Ivan Bryzzhin
źródło
3
Jestem zdumiony tą prostotą! Python x or yjest if x is false, then y, else x. Patrz: 5.2. Operacje boolowskie - i lub nie
kenjiuno
10

Korzystając z tego dokumentu, możesz to zrobić w następujący sposób:

{{ p.User['first_name']|default('NONE') }}
pawel7318
źródło
8
Nie sądzę - „domyślny” filtr szablonu zwraca wartość domyślną, jeśli wartość jest niezdefiniowana / jej brakuje.
codeape
Pracował dla mnie podczas używania ansible. To uczyniło sprawę bardziej przejrzystą: stackoverflow.com/q/28885184/1005215
Nehal J Wani
1
Jeśli zdefiniowano p. Ale jeśli P nie jest zdefiniowane, nie działa
dalore
5

Aby uniknąć zgłaszania wyjątku, gdy „p” lub „p.User” ma wartość None, możesz użyć:

{{ (p and p.User and p.User['first_name']) or "default_value" }}
Pod
źródło
4
To jedyny, który działał dla mnie, biorąc pod uwagę, że moja zmienna była głęboko zakorzeniona w dyktandzie.
Craicerjack
Pomaga to uporządkować inne z dużą ilością logiki.
eagle33322
1

Jako inne rozwiązanie (trochę podobne do niektórych poprzednich):

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

Zauważ, że ostatnia zmienna (p.User ['first_name']) nie ma po sobie if definedtestu.

Apollo
źródło
0

Zwykle definiuję nvlfunkcję i umieszczam ją w globalsi 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

Wykorzystanie w szablonie:

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

// or 

<span>Welcome {{ person.nick | nvl(person.name, 'Anonymous') }}<span>
Tamas Hegedus
źródło