68

How do I persuade Jinja2 to not print "None" when the value is None?

I have a number of entries in a dictionary and I would like to output everything in a single loop instead of having special cases for different keywords. If I have a value of None (the NoneType not the string) then the string "None" is inserted into the template rendering results.

Trying to suppress it using {{ value or '' }} works too well as it will replace the numeric value zero as well.

Do I need to filter the dictionary before passing it to Jinja2 for rendering?

OJFord
  • 10,522
  • 8
  • 64
  • 98
Spaceghost
  • 6,835
  • 3
  • 28
  • 42

5 Answers5

75

In new versions of Jinja2 (2.9+):

{{ value if value }}

In older versions of Jinja2 (prior to 2.9):

{{ value if value is not none }} works great.

if this raises an error about not having an else try using an else ..

{{ value if value is not none else '' }}

zor-el
  • 320
  • 2
  • 11
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
36

Another option is to use the finalize hook on the environment:

>>> import jinja2
>>> e = jinja2.Environment()
>>> e.from_string("{{ this }} / {{ that }}").render(this=0, that=None)
u'0 / None'

but:

>>> def my_finalize(thing):
...     return thing if thing is not None else ''
...
>>> e = jinja2.Environment(finalize=my_finalize)
>>> e.from_string("{{ this }} / {{ that }}").render(this=0, that=None)
u'0 / '
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • I think this is the smartest way to do it. However, when I tried this method with FastAPI's jinja2, `url_for()` in the template stopped working. For your information. – mitsu Dec 22 '21 at 04:28
29

Default filter:

{{ value|default("", True) }}
Mads Skjern
  • 5,648
  • 6
  • 36
  • 40
solarc
  • 5,638
  • 2
  • 40
  • 51
  • 1
    this has the same problem as OP's main solution... I think this would work as {{ value|default("", **True** ) }} – Joran Beasley Jun 21 '12 at 21:39
  • 1
    Without the True, this doesn't work at all. With the True, it replaces the None and the numeric zero .. so no good. – Spaceghost Jun 21 '12 at 21:42
  • You are right, it only works when the variable isn't defined instead of assigning None to it. But writing a filter for the None case would be worth it just for being less verbose than the chosen answer. – solarc Jun 21 '12 at 23:07
  • 1
    I like this solution the best. – corvid Aug 12 '14 at 01:08
23

A custom filter can solve the problem. Declare it like this:

def filter_suppress_none(val):
    if not val is None:
        return val
    else:
        return ''

Install it like this:

templating_environment.filters['sn'] = filter_suppress_none

Use it like this:

{{value|sn}}
AlexVhr
  • 2,014
  • 1
  • 20
  • 30
22

According to this post from the Pocco Mailing List: https://groups.google.com/d/msg/pocoo-libs/SQ9ubo_Kamw/TadIdab9eN8J

Armin Ronacher (creater of Jinja2/Flask, etc...) recommends the following "pythonic" snippet:

{{ variable or 0 }} {{ variable or '' }}

The notion here being that once again, explicit is preferable to implicit.

Edit: The selected answer is definitely the correct one. I haven't really come across a situation where a template variable would be either a string or the numeric zero, so the above snippets might help reduce the code noise in the template.

Brownbay
  • 5,400
  • 3
  • 25
  • 30