Переменная шаблона 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! = None%} {{p.User ['first_name']}} {% endif%}   -  person Mona Mohamadinia    schedule 23.12.2018
comment
См. Также: Как в Jinja2 проверить, не определена ли переменная?   -  person Martin Thoma    schedule 22.06.2019


Ответы (9)


Используйте none test (не путать с _ 2_ объект!):

{% 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

Согласно docs, вы можете просто сделать:

{{ 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. Логические операции - and, or, not - person kenjiuno; 22.11.2017

Следуя этому документу, вы можете сделать это следующим образом:

{{ p.User['first_name']|default('NONE') }}
person pawel7318    schedule 03.06.2014
comment
Я так не думаю - фильтр шаблона по умолчанию возвращает значение по умолчанию, если значение не определено / отсутствует. - person codeape; 14.10.2014
comment
У меня сработало при использовании ансибла. Это сделало его более понятным: 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
Это единственное, что сработало для меня, учитывая, что моя переменная была похоронена глубоко в диктовке. - 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

Вы можете просто добавить значение по умолчанию none к своей переменной, как указано в приведенной ниже форме:

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