Jinja2模板变量如果为None对象则设置默认值

242
如何让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'

1
编写一个函数,使其返回p的值时不会返回None。该函数应该返回一个代理对象,该对象具有与真实对象相同的结构,但是它加载了您想要的默认值。 - Miguel Grinberg
1
我使用了这个代码,我的问题得到了解决: {% if p != None %} {{ p.User['first_name'] }} {% endif %} - Mona Mohamadinia
13个回答

396

使用none测试(不要与Python的None对象混淆):

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

或者如果你需要一个空字符串:

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

44
注意回答中小写的单词none。我在纠正None的大小写后解决了我的问题。 - harperville
5
这是最好的答案,因为许多其他答案没有区分“False”和“None”。此示例使用术语“first_name”,我们可以假设它不期望一个“False”的值,但有许多情况下,系统需要以不同方式处理“False”和“None”。像{{p.User['first_name'] or 'default'}}这样的东西将无法捕获该情况,并会错误地将“False”转换为默认情况。其他有趣的情况包括 0[]"" - Jamie Counsell
有点奇怪为什么 != None 能起作用,但 is not None 却不行,为此,你需要使用小写字母:is not none - undefined

172
{{p.User['first_name'] or 'My default string'}}

1
当与布尔值一起使用时,这可能会导致自己被打脚吗?例如,如果 p.User['first_name']false,那么结果是否符合预期:false - Rots

108
根据文档,你可以这样做:
{{ p|d('', true) }}

在布尔上下文中,None会被强制转换为False


9
这适用于简单变量,但不适用于你想从更复杂的字段中获取值的情况。我会对这个答案进行负投票,因为它不能很好地回答原始问题...但同时,了解“default”正是我在特定情况下所需要的,所以......我选择不投票。(修改此答案可能会让它获得赞成票,但我认为在这种情况下应用“default”可能很困难) - lindes
1
我认为关于default仅适用于简单数据类型的提及已经过时了。我已经使用空列表default([])使其正常工作。 - NicoE

58

作为其他答案的补充,如果变量是None,可以像这样编写其他内容:

{{ variable or '' }}

5
我很惊讶这么简单!Python 的 x or y 意为:如果 x 是假的,则返回 y,否则返回 x。参见:5.2. Boolean Operations — and, or, not - kenjiuno
1
这个方法对我有效,而其他方法都失败了。 - n_moen

22

根据这个文档,您可以以下方式进行:

{{ p.User['first_name']|default('NONE') }}

10
我不这么认为 - “default”模板过滤器会在值未定义或缺失时返回默认值。 - codeape
1
在使用ansible时对我很有用。这个链接让它更清晰:https://dev59.com/bF4b5IYBdhLWcg3woS68 - Nehal J Wani
1
如果p被定义了,那么它可以工作。但是如果p没有被定义,它将不起作用。 - dalore

7
为了避免在“p”或“p.User”为空时抛出异常,您可以使用以下方法:
{{ (p and p.User and p.User['first_name']) or "default_value" }}

5
这是唯一一个对我起作用的方法,因为我的变量被深深地嵌套在字典中。 - Craicerjack
这有助于清理一些具有大量逻辑的其他内容。 - eagle33322

7

使用 ChainableUndefined,你可以做到这一点。

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

源代码


1
如果你想设置一个自己的默认值而不是使用None,那么只需这样做: {{your_var|default:'default name'}}

0
作为另一种解决方案(与之前的某些解决方案有点类似):
{{ ( p is defined and p.User is defined and p.User['first_name'] ) |default("NONE", True) }}

请注意最后一个变量(p.User ['first_name'])之后没有经过if defined测试。

0

我通常会定义一个nvl函数,并将其放在globalsfilters中。

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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接