Променлива на шаблон Jinja2, ако None Object зададе стойност по подразбиране

Как да направите променлива в jijna2 по подразбиране на "", ако обектът е None, вместо да правите нещо подобно?

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

Така че, ако обектът p е None, искам да задам по подразбиране стойностите на p (first_name и last_name) на "". По принцип

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

Грешка при получаване:

Error:  jinja2.exceptions.UndefinedError
    UndefinedError: 'None' has no attribute 'User'

person mcd    schedule 27.10.2013    source източник
comment
Направете функцията, която е върнала стойността на p, никога да не връща None. Вместо None функцията трябва да върне прокси обект, който има същата структура като реален обект, но е зареден със стойностите по подразбиране, които искате.   -  person Miguel    schedule 27.10.2013
comment
Използвам това и проблемът ми беше разрешен: {% if p != Няма %} {{ p.User['first_name'] }} {% endif %}   -  person Mona Mohamadinia    schedule 23.12.2018
comment
Вижте също: В Jinja2, как тествате дали дадена променлива е недефинирана?   -  person Martin Thoma    schedule 22.06.2019


Отговори (9)


Използвайте none тест (да не се бърка с None обект!):

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

or:

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

или ако имате нужда от празен низ:

{{ p.User['first_name'] if p is not none }}
person tbicr    schedule 27.10.2013
comment
Обърнете внимание на малката буква none в отговора. Проблемът ми беше разрешен, след като коригирах случая на None. - person harperville; 09.06.2016
comment
Това е най-добрият отговор, защото толкова много други не правят разлика между False и None. Този пример използва термина "first_name", който можем да предположим, че няма да очаква стойност False, но има много случаи, в които системата трябва да третира False и None по различен начин. Неща като {{p.User['first_name'] or 'default'}} няма да уловят този регистър и ще преобразуват неправилно False в регистъра по подразбиране. Други интересни случаи са 0, [] и "". - person Jamie Counsell; 03.03.2021

Според документи можете просто да направите:

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

Причина None прехвърля към False в булев контекст.


Актуализация: Както Линдес спомена, работи само за прости типове данни.

person mitenka    schedule 23.03.2015
comment
Това работи за проста променлива, но не и за този въпрос, при който търсите да вземете поле от по-сложно. Бих гласувал против това, тъй като не е добър отговор на първоначалния въпрос... и все пак в същото време знанието за default е точно това, от което имах нужда за моя конкретен случай, така че... просто не гласувам. (Една редакция на този отговор може да му спечели положително гласуване, освен че мисля, че вероятно е трудно да се приложи default към тази ситуация) - person lindes; 24.10.2015
comment
Мисля, че споменаването относно default работи само в прости типове данни е остаряло. Това работи с празен списък, default([]) - person NicoE; 27.04.2021

Като допълнение към други отговори, човек може да напише нещо друго, ако променливата е None по този начин:

{{ variable or '' }}
person Ivan Bryzzhin    schedule 05.02.2017
comment
Изумен съм от тази простотия! x or y на Python е if x is false, then y, else x. Вижте: 5.2. Булеви операции — и, или, не - person kenjiuno; 22.11.2017

Следвайки този документ можете да направите това по следния начин:

{{ p.User['first_name']|default('NONE') }}
person pawel7318    schedule 03.06.2014
comment
Не мисля така - филтърът на шаблона по подразбиране връща стойността по подразбиране, ако стойността е недефинирана/липсваща. - person codeape; 14.10.2014
comment
Работи за мен, когато използвам ansible. Това го направи по-ясно: stackoverflow.com/q/28885184/1005215 - person Nehal J Wani; 17.11.2016
comment
Ако p е дефинирано. Но ако P не е дефинирано, това не работи - person dalore; 28.06.2017

За да избегнете хвърляне на изключение, докато "p" или "p.User" е None, можете да използвате:

{{ (p and p.User and p.User['first_name']) or "default_value" }}
person Sub    schedule 25.10.2017
comment
Това е единственият, който работи за мен, тъй като моята променлива беше заровена дълбоко в dict. - person Craicerjack; 13.12.2017
comment
Това помага да се изчистят някои други с много логика. - person eagle33322; 25.11.2019

Като друго решение (нещо подобно на някои предишни):

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

Забележете, че последната променлива (p.User['first_name']) няма if defined теста след нея.

person Apollo    schedule 02.05.2019

Обикновено дефинирам функция nvl и я поставям в globals и 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

Използване в шаблон:

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

// or 

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

От Ansible 2.8 можете просто да използвате:

{{ p.User['first_name'] }}

Вижте https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html#jinja-undefined-values

person Apollo    schedule 15.06.2019

Можете просто да добавите нищо по подразбиране към вашата променлива, както е посочено във формата по-долу:

{{ your_var | default('NONE', boolean=true) }}
person yelmir    schedule 29.12.2020