Jinja2忽略未找到的对象的UndefinedErrors

时间:2011-05-31 16:03:04

标签: python jinja2

我从Django切换到Jinja但是在引用

时我的很多模板都破了
 {{ entity.property }}

如果未定义实体。在某些情况下是否会忽略UndefinedErrors,否则我将不得不添加很多

 {% if entity %}{{ entity.property }}{% endif %}

包装。

谢谢, 理查德

6 个答案:

答案 0 :(得分:7)

基于肖恩出色而有用的答案,我做了以下几点:

from jinja2 import Undefined
import logging

class SilentUndefined(Undefined):
    '''
    Dont break pageloads because vars arent there!
    '''
    def _fail_with_undefined_error(self, *args, **kwargs):
        logging.exception('JINJA2: something was undefined!')
        return None

然后env = Environment(undefined=SilentUndefined)我在那里打电话。

在我使用的django_jinja库中,上面的内容位于base.py,实际上是initial_params的修改

答案 1 :(得分:4)

Jinja2实际上为未定义的实体使用了一个特殊类。您可以从Jinja2继承此Undefined类,以包含__getattr__和其他attribute accessors,您希望它们能够在未定义的实体上使用,并让它们返回空白的unicode字符串(例如)

答案 2 :(得分:4)

我还需要重置类的魔术方法,以使对象属性等正常工作。添加到@rattray -

from jinja2 import Undefined, Template

class SilentUndefined(Undefined):
    def _fail_with_undefined_error(self, *args, **kwargs):
        return ''

    __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
        __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
        __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
        __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
        __float__ = __complex__ = __pow__ = __rpow__ = \
        _fail_with_undefined_error        

成为一个jinja设置是有道理的。很多人都会来自django模板,默认情况下是沉默的。

答案 3 :(得分:2)

我建立在@ rattray的答案之上:

from jinja2 import Undefined, Template

class SilentUndefined(Undefined):
    def _fail_with_undefined_error(self, *args, **kwargs):
        return ''

然后将它与模板字符串一起使用:

person_dict = {'first_name': 'Frank', 'last_name': 'Hervert'}
t2 = Template("{{ person1.last_name }}, {{ person.last_name }}", undefined=SilentUndefined)

print t2.render({'person': person_dict})                                                                         
# ', Hervert'

我需要在从字符串直接渲染模板时忽略错误,而不是使用Environment。

答案 4 :(得分:1)

也正在寻找解决方案并使用@ s29 SilentUndefined类,但我已经抓住了#34;' str'对象不可调用"尝试调用未定义变量时出错,所以这是我的解决方法,它可能对某人有用

class SilentUndefined(Undefined):

    def _fail_with_undefined_error(self, *args, **kwargs):
        class EmptyString(str):
            def __call__(self, *args, **kwargs):
                return ''
        return EmptyString()

 __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
    __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
    __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
    __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
    __float__ = __complex__ = __pow__ = __rpow__ = \
    _fail_with_undefined_error

答案 5 :(得分:0)

如果您在ansible中使用Jinja2,则可以使用一个设置为缺失的变量指定默认行为。在ansible.cfg中:

[Defaults]
error_on_undefined_vars=False

请注意,这和默认过滤器仅在点路径的末尾缺少的情况下有效。例如:{{ a.b.c }}如果缺少'c'将起作用,但是如果缺少'b'则仍将失败并出现KeyError。