237

How to make a variable in jijna2 default to "" if object is None instead of doing something like this?

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

So if object p is None I want to default the values of p (first_name and last_name) to "". Basically

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

Error receiving:

Error:  jinja2.exceptions.UndefinedError
    UndefinedError: 'None' has no attribute 'User'
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
mcd
  • 6,446
  • 9
  • 27
  • 32
  • 1
    Make the function that returned the value of `p` never return `None`. Instead of `None` the function should return a proxy object that has the same structure as a real object but it is loaded with the default values that you want. – Miguel Grinberg Oct 27 '13 at 04:23
  • I use this, and my problem was solved: {% if p != None %} {{ p.User['first_name'] }} {% endif %} – Mona Mohamadinia Dec 23 '18 at 14:53
  • See also: [In Jinja2, how do you test if a variable is undefined?](https://stackoverflow.com/q/3842690/562769) – Martin Thoma Jun 22 '19 at 05:02

13 Answers13

382

Use the none test (not to be confused with Python's None object!):

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

or:

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

or if you need an empty string:

{{ p.User['first_name'] if p is not none }}
costaparas
  • 5,047
  • 11
  • 16
  • 26
tbicr
  • 24,790
  • 12
  • 81
  • 106
  • 41
    Notice the lowercase `none` in the answer. My problem was solved after I corrected None's case. – harperville Jun 09 '16 at 17:03
  • 5
    This is the best answer because so many others do not differentiate between `False` and `None`. This example uses the term `"first_name"` which we can assume will not expect a value of `False`, but there are many cases where a system needs to treat `False` and `None` differently. Things like `{{p.User['first_name'] or 'default'}}` will not catch that case and will convert `False` to the default case incorrectly. Other interesting cases are `0`, `[]`, and `""`. – Jamie Counsell Mar 03 '21 at 18:34
171
{{p.User['first_name'] or 'My default string'}}
Torindo
  • 1,855
  • 1
  • 11
  • 3
  • 1
    This might be shooting in the foot when using with boolean values? I.e. if `p.User['first_name']` is `false` will the result be as expected: `false`? – Rots Oct 18 '21 at 14:38
106

According to docs you can just do:

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

Cause None casts to False in a boolean context.

mitenka
  • 1,365
  • 1
  • 10
  • 10
  • 9
    This works for a simple variable, but not for this question where you're looking to grab a field out of a more complex one. I would downvote this, since it's not a good answer to the original question... and yet at the same time, knowing about `default` is exactly what I needed for my particular case, so... simply not voting. (An edit to this answer might well earn it an upvote, except that I think it's likely hard to apply `default` to this situation) – lindes Oct 24 '15 at 14:42
  • 1
    I think the mention regarding `default` only works in *simple* data types is outdated. I have this working with an empty list, `default([])` – NicoE Apr 27 '21 at 19:14
57

As addition to other answers, one can write something else if variable is None like this:

{{ variable or '' }}
Ivan Bryzzhin
  • 2,009
  • 21
  • 27
  • 5
    I am amazed this simplicity! Python's `x or y` is `if x is false, then y, else x`. See: [5.2. Boolean Operations — and, or, not](https://docs.python.org/2/library/stdtypes.html#boolean-operations-and-or-not) – kenjiuno Nov 22 '17 at 02:28
  • 1
    This worked for me where others failed. – arcanemachine Mar 07 '22 at 21:33
21

Following this doc you can do this that way:

{{ p.User['first_name']|default('NONE') }}
pawel7318
  • 3,383
  • 2
  • 28
  • 44
7

To avoid throw a exception while "p" or "p.User" is None, you can use:

{{ (p and p.User and p.User['first_name']) or "default_value" }}
Guoqiang
  • 307
  • 3
  • 6
7

With ChainableUndefined, you can do that.

>>> import jinja2
>>> env = jinja2.Environment(undefined=jinja2.ChainableUndefined)
>>> env.from_string("{{ foo.bar['baz'] | default('val') }}").render()
'val'

source

kirosc
  • 154
  • 1
  • 7
1

if you want to set your own default value instead of None than simply do this

{{your_var|default:'default name'}}

tarun kumar
  • 148
  • 3
  • 10
0

I usually define an nvl function, and put it in globals and 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

Usage in a template:

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

// or 

<span>Welcome {{ person.nick | nvl(person.name, 'Anonymous') }}<span>
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
0

As another solution (kind of similar to some previous ones):

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

Note the last variable (p.User['first_name']) does not have the if defined test after it.

Apollo
  • 5
  • 1
0

I solved this by defining a custom filter (in my case I needed in the cases None, False or empty strings):

def __default_if_empty(value, default) :
    """Returns a default value if the given value evaluates to False."""
    return value if value else default

env = Environment(
    # Your config...
)
env.filters["default_if_empty"] = __default_if_empty

Then use that filter in the template:

{{ your_var | default_if_empty('') }}
Genarito
  • 3,027
  • 5
  • 27
  • 53
-2

As of Ansible 2.8, you can just use:

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

See https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.8.html#jinja-undefined-values

Apollo
  • 5
  • 1
-2

You can simply add "default none" to your variable as the form below mentioned:

{{ your_var | default('NONE', boolean=true) }}
rcv
  • 6,078
  • 9
  • 43
  • 63
yelmir
  • 13
  • 4