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 " отсутствует.