Jinja2: if и for
"Перед прочтением этой статьи советуем ознакомиться с тем, что такое Jinja. Это можно сделать в предыдущей нашей статье.
В предыдущей статье вы узнали как подставлять переменные в шаблон. Мы создали 6 переменных и подставили их в три карточки:
rendered_page = template.render(
cap1_title="Красная кепка",
cap1_text="$ 100.00",
cap2_title="Чёрная кепка",
cap2_text="$ 120.00",
cap3_title="Ещё одна чёрная кепка",
cap3_text="$ 90.00",
)
Эта схема совершенно не расширяемая: а что, если товаров в магазине будет 12? Создавать 24 переменные? Нет, вместо этого можно создать список из объектов и пройти его в цикле прямо внутри HTML-шаблона.
В этой статье мы рассмотрим if
и for
в шаблонах Jinja.
Цикл for
Начнём с вывода 6 карточек одной и той же кепки. У каждой карточки есть свой блок вёрстки. Как его найти можно прочитать здесь.
Мы его нашли, вот он:
...
<div class="col-4">
<div class="card">
<img src="https://dvmn.org/filer/canonical/1569333143/329/" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">New York Yankees</h5>
<p class="card-text">Красная кепка NY Yankees за 20$ снова в продаже!</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
...
Далее хочется её продублировать 6 раз. Для этого в Jinja есть range()
, такой же, как в Python:
...
{% for index in range(6) %}
<div class="col-4">
<div class="card">
<img src="https://dvmn.org/filer/canonical/1569333143/329/" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">New York Yankees</h5>
<p class="card-text">Красная кепка NY Yankees за 20$ снова в продаже!</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
{% endfor %}
...
Итак, мы просто добавили {% for index in range(6) %}
сверху и {% endfor %}
снизу. В целом, это тот же for
из Python, просто он заключён в значки {% %}
и в конце указывается {% endfor %}
. После запуска main.py
появится index.html
с таким результатом:
Итерация по списку
6 одинаковых карточек — это не интересно. Карточки можно сделать разными, если названия кепок и их цены брать из списка. Добавим в main.py
список из словарей с данными о кепках:
caps = [
{
"title": "Красная кепка",
"price": "$ 100.00",
"image": "https://dvmn.org/filer/canonical/1569333143/329/"
},
...
]
Полную верию данных можно найти здесь
Теперь вы можете передать в шаблон сразу список словарей:
rendered_page = template.render(caps=caps)
В шаблоне можно написать цикл по списку caps
:
{% for cap in caps %}
<div class="col-4">
<div class="card">
<img src="{{cap.image}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{cap.title}}</h5>
<p class="card-text">{{cap.price}}</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
</div>
</div>
</div>
{% endfor %}
Обратите внимание: к элементам словаря доступ идёт через точку: {{cap.image}}
. В остальном, это почти такой же цикл, как и с range
. После запуска main.py
получается такой результат:
Условия if
Предположим, что у некоторых товаров ещё нет картинки. Что же делать? Без неё, на странице будет уродливая ошибка:
В такой ситуации поможет if
. Давайте, если картинки нет, заменять её на “стандартную” картинку. Делается это очень просто:
{% if cap.image %}
<img src="{{cap.image}}" class="card-img-top" alt="...">
{% else %}
<img src="https://dvmn.org/filer/canonical/1569944855/354/" class="card-img-top" alt="...">
{% endif %}
Условия в Jinja2 работают так же, как и в Python. Если картинка есть, сработает тот блок, что выше, а если нет — тот, что ниже. Получится такой результат:
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.