Шаблоны Jinja
Собирать HTML из строк вручную неудобно и опасно. Во Flask для этого есть шаблоны Jinja — HTML с местами для подстановки данных.
Шаблоны в файлах и в строке
Обычно шаблоны лежат в папке templates рядом с программой:
from flask import render_template
@app.route("/")
def index():
return render_template("index.html", name="Аня", skills=["Python", "SQL"])
В задачах курса шаблон хранится прямо в коде, в строке — так вся программа в одном файле:
from flask import render_template_string
PAGE = "<h1>Привет, {{ name }}!</h1>"
return render_template_string(PAGE, name="Аня")
Работают обе функции одинаково: шаблон и именованные аргументы — данные для него.
Подстановки, условия и циклы
<h1>{{ title }}</h1>
{% if skills %}
<ul>
{% for s in skills %}
<li>{{ loop.index }}. {{ s }}</li>
{% endfor %}
</ul>
{% else %}
<p>Пока пусто</p>
{% endif %}
{{ … }}— вывести значение;{% … %}— команда:if / elif / else / endif,for / endfor;- внутри цикла есть
loop.index(с единицы),loop.index0(с нуля),loop.first,loop.last,loop.length; - к полям словаря и объекта обращаются через точку:
{{ user.name }}.
Фильтры
{{ name|upper }} АНЯ
{{ name|capitalize }} Аня
{{ items|length }} 3
{{ items|join(", ") }} a, b, c
{{ price|round(1) }} 9.9
{{ bio|default("—") }} если bio не задан
Сортировать и считать лучше в Python, в функции-представлении, а шаблону передавать уже готовые данные: шаблон только показывает.
Экранирование
Всё, что выводится через {{ }}, Flask экранирует: < превращается в <, > — в >, & — в &, кавычки — в " и '. Поэтому, если посетитель впишет в форму <script>…</script>, на странице появится просто текст, а не программа.
Фильтр |safe отключает экранирование. Используйте его только для HTML, который написали вы сами, — никогда для данных от посетителей. Иначе злоумышленник встроит на ваш сайт свой скрипт (атака XSS).
Итог
render_template(файл изtemplates) иrender_template_string(строка);{{ }}— значение,{% if %},{% for %},loop.index;- фильтры
upper,capitalize,length,join,default; - автоэкранирование защищает от XSS;
|safe— только для своего HTML.