Jinja2 игнорировать UndefinedErrors для объектов, которые не нашли

я переключился на Jinja из Django, но многие мои шаблоны сломались при ссылке

 {{ entity.property }}

если сущность не определена. Там далеко, чтобы игнорировать UndefinedErrors в определенных ситуациях, в противном случае мне придется добавить в массу

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

фантики.

спасибо, Ричард!--3-->

6 ответов


Jinja2 фактически использует специальный класс для неопределенных лиц. Вы можете подкласс это Undefined класс от Jinja2, чтобы включить __getattr__ и другие аксессоры атрибут которые вы хотите использовать даже для неопределенных сущностей и возвращать пустую строку unicode (например).


основываясь на отличном и полезном ответе Шона, я сделал следующее:

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


мне также нужно было сбросить магические методы класса, чтобы атрибуты объекта и т. д. работали правильно. Добавление в @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, которые по умолчанию молчат.


Я построил на ответе @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'

мне нужно было игнорировать ошибки при рендеринге шаблона из строки непосредственно вместо использования среды.


также искал решение и использовал @ s29 SilentUndefined class, но я поймал ошибку "' STR 'object is not callable" при попытке вызвать неопределенную переменную, так что это мой обходной путь, это может быть полезно для кого-то

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

Если вы используете Jinja2 в ansible, есть параметр, который позволяет указать поведение по умолчанию для отсутствующей переменной. В анзибль.cfg следующее:

[Defaults]
error_on_undefined_vars=False

обратите внимание, что это и фильтр по умолчанию работают, только если то, что отсутствует, находится в конце пути точки. Например:{{ a.b.c }} будет работать, если " c "отсутствует, но все равно не удастся с KeyError, если" b " отсутствует.