Обработка исключений Jinja2

#ansible #jinja2 #python-textfsm

#python #шаблоны #исключение #django-шаблоны #jinja2

Вопрос:

Есть ли способ обрабатывать исключения внутри шаблона в jinja2?

 {% for item in items %}
   {{ item|urlencode }}  <-- item contains a unicode string that contains a character causes urlencode to throw KeyError
{% endfor %}
  

Как мне обработать это исключение, чтобы я мог просто пропустить этот элемент или обработать его, не вызывая сбоя рендеринга всего шаблона?

Спасибо!

Комментарии:

1. Я не думаю, что {% try %} в jinja есть (или эквивалент). Насколько я понимаю, ваши варианты — написать версию, защищенную от исключений urlencode , и использовать ее в качестве фильтра или очистить входные данные перед передачей их в jinja2.

2. 1 по очистке списка элементов перед передачей его Jinja

Ответ №1:

 {% for item in items %}
   {{ item | custom_urlencode_filter }}
{% endfor %}
  

Затем в любом файле, который у вас есть, настраивается среда jinja2

 def custom_urlencode_filter(value):
    try:
        return urlencode(value)
    except:
        # handle the exception


environment.filters['custom_urlencode_filter'] = custom_urlencode_filter
  

Подробнее о пользовательских фильтрах jinja2

Комментарии:

1. Спасибо, что объяснили это более подробно. Это лучший ответ! 🙂

2. Альтернативой environment.filters является передача функции в ваш шаблон. В маршруте: return render_template('yourpage.html', custom_urlencode_filter=custom_urlencode_filter) и в шаблоне: {{ custom_urlencode_filter(item) }}

Ответ №2:

Хотя jinja2 не имеет способа справиться с этим по умолчанию, существует обходной путь.

Поскольку try не поддерживается на языке шаблонов, нам нужна вспомогательная функция, определенная на Python, например:

 def handle_catch(caller, on_exception):
    try:
         return caller()
    except:
         return on_exception
  

Этот метод вводится в механизм шаблонов либо через Environment.globals or, либо при вызове метода render . В этом примере он вводится с помощью метода render .

 my_template.render(handle_catch=handle_catch)
  

Затем в самом шаблоне можно определить макрос:

 {% macro catch(on_exception) %}
    {{ handle_catch(caller, on_exception) }}
{% endmacro %}
  

И затем это можно использовать как:

 {% for item in items %}
   {% call catch('') %}
       {{ item | custom_urlencode_filter }}
   {% endcall %}
{% endfor %}
  

Примечания:

  • Вызывающий метод предоставляется jinja2, и это функция, которая отображает код между {% call ... %} и {% endcall %}
  • on_exception может использоваться для предоставления альтернативного текста в случае исключений, но в этом случае мы просто используем пустую строку.

Ответ №3:

Их нет. Просто обрабатывайте исключения в функции фильтра urlencode.