【问题标题】:Jinja2 template variable if None Object set a default value如果 None 对象设置默认值,Jinja2 模板变量
【发布时间】:2013-11-05 23:59:06
【问题描述】:

如果对象为None,如何使jijna2中的变量默认为“”而不是做这样的事情?

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

【问题讨论】:

  • 使返回p 值的函数永远不会返回None。而不是None,该函数应该返回一个代理对象,它与真实对象具有相同的结构,但它加载了您想要的默认值。
  • 我用这个,我的问题解决了:{% if p != None %} {{ p.User['first_name'] }} {% endif %}

标签: jinja2


【解决方案1】:

使用none test(不要与Python的None object混淆!):

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

【讨论】:

  • 请注意答案中的小写none。在我纠正了 None 的情况后,我的问题得到了解决。
  • 这是最好的答案,因为很多其他人不区分 FalseNone。此示例使用术语"first_name",我们可以假设它不会期望值False,但在许多情况下,系统需要区别对待FalseNone。像{{p.User['first_name'] or 'default'}} 这样的东西不会捕捉到这种情况,并且会错误地将False 转换为默认情况。其他有趣的案例还有0[]""
【解决方案2】:
{{p.User['first_name'] or 'My default string'}}

【讨论】:

  • 与布尔值一起使用时,这可能是在踢脚? IE。如果p.User['first_name']false,结果是否如预期:false?
【解决方案3】:

根据docs,您可以这样做:

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

因为 None 在布尔上下文中转换为 False

【讨论】:

  • 这适用于简单变量,但不适用于您希望从更复杂的字段中获取字段的问题。我会对此投反对票,因为这不是对原始问题的一个很好的答案……但同时,了解default 正是我在特定情况下所需要的,所以……根本不投票。 (对此答案的编辑很可能会获得支持,但我认为可能很难将default 应用于这种情况)
  • 我认为提及default 仅适用于 simple 数据类型已过时。我有一个空列表,default([])
【解决方案4】:

作为其他答案的补充,如果 variable 是 None ,可以写其他东西,如下所示:

{{ variable or '' }}

【讨论】:

【解决方案5】:

按照this doc,您可以这样做:

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

【讨论】:

  • 我不这么认为 - 如果值未定义/缺失,“默认”模板过滤器会返回默认值。
  • 在使用 ansible 时为我工作。这更清楚了:stackoverflow.com/q/28885184/1005215
  • 如果定义了 p。但是,如果没有定义 P,它就不起作用
【解决方案6】:

为避免在“p”或“p.User”为 None 时引发异常,您可以使用:

{{ (p and p.User and p.User['first_name']) or "default_value" }}

【讨论】:

  • 这是唯一对我有用的,因为我的变量深埋在字典中。
  • 这有助于清理其他一些有很多逻辑的东西。
【解决方案7】:

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

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

source

【讨论】:

    【解决方案8】:

    作为另一种解决方案(类似于以前的一些解决方案):

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

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

    【讨论】:

      【解决方案9】:

      如果你想设置自己的默认值而不是 None ,那么就这样做

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

      【讨论】:

        【解决方案10】:

        我一般定义一个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>
        

        【讨论】:

          【解决方案11】:

          从 Ansible 2.8 开始,您可以使用:

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

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

          【讨论】:

            【解决方案12】:

            您可以简单地将“默认无”添加到您的变量中,如下所述:

            {{ your_var | default('NONE', boolean=true) }}
            

            【讨论】:

              猜你喜欢
              • 2012-02-27
              • 1970-01-01
              • 2020-03-19
              • 2013-03-23
              • 2019-03-31
              • 2014-10-23
              • 1970-01-01
              相关资源
              最近更新 更多