Как мы уже говорили ранее, шаблонная система поставляется со встроенными тегами и фильтрами. Следующие разделы описывают основные теги и шаблоны.
Тег {% if %} вычисляет переменную и если результатом вычисления является True (т.е., она существует, не пустая и не равна False), система отображает всё между {% if %} и {% endif %}, например:
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% endif %}
Тег {% else %} является необязательным:
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
«Истина» в Python
В Python и в шаблонной системе Django нижеприведённые
объекты вычисляются в False в контексте
Boolean:
Пустой список ([]);
Пустой кортеж (());
Пустой словарь ({});
Ноль (0);
Особый объект
None;Объект
False(это очевидно);Особые объекты, которые определяют их собственное поведение
Boolean(это питонские навороты).
Всё остальное вычисляется в True.
Тег {% if %} принимает and, or или not для тестирования множества переменных или инвертирования. Например:
{% if athlete_list and coach_list %}
Both athletes and coaches are available.
{% endif %}
{% if not athlete_list %}
There are no athletes.
{% endif %}
{% if athlete_list or coach_list %}
There are some athletes or some coaches.
{% endif %}
{% if not athlete_list or coach_list %}
There are no athletes or there are some coaches.
{% endif %}
{% if athlete_list and not coach_list %}
There are some athletes and absolutely no coaches.
{% endif %}
Можно использовать and и or вместе. Помните, and имеет больший приоритет. Например:
{% if athlete_list and coach_list or cheerleader_list %}
будет интерпретировано как:
if (athlete_list and coach_list) or cheerleader_list
Использование скобок для управления порядком операций не поддерживается. Если вам потребуются скобки, рассмотрите применение логики вне шаблона и передачу результата вычисления в виде выделенной шаблонной переменной. Или просто используйте вложенные теги {% if %}, например:
{% if athlete_list %}
{% if coach_list or cheerleader_list %}
We have athletes, and either coaches or cheerleaders!
{% endif %}
{% endif %}
Допускается множественное использование одного и того же логического оператора:
{% if athlete_list or coach_list or parent_list or teacher_list %}
Также возможно использовать операторы ==, !=, <, >, >=, <= и in:
{% if somevar == "x" %}
This appears if variable somevar equals the string "x"
{% endif %}
{% if somevar != "x" %}
This appears if variable somevar does not equal the string "x",
or if somevar is not found in the context
{% endif %}
{% if somevar < 100 %}
This appears if variable somevar is less than 100.
{% endif %}
{% if somevar > 0 %}
This appears if variable somevar is greater than 0.
{% endif %}
{% if somevar <= 100 %}
This appears if variable somevar is less than 100 or equal to 100.
{% endif %}
{% if somevar >= 1 %}
This appears if variable somevar is greater than 1 or equal to 1.
{% endif %}
{% if "bc" in "abcdef" %}
This appears since "bc" is a substring of "abcdef"
{% endif %}
{% if "hello" in greetings %}
If greetings is a list or set, one element of which is the string
"hello", this will appear.
{% endif %}
{% if user in users %}
If users is a QuerySet, this will appear if user is an
instance that belongs to the QuerySet.
{% endif %}
Тега {% elif %} не существует. Используйте вложенные теги {% if %} для решения такой задачи:
{% if athlete_list %}
<p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
<p>No athletes are available.</p>
{% if coach_list %}
<p>Here are the coaches: {{ coach_list }}.</p>
{% endif %}
{% endif %}
Не забывайте закрывать каждый тег {% if %} с
помощью {% endif %}. В противном случае
Django будет вызывать исключение
TemplateSyntaxError.
Тег {% for %} позволяет обработать каждый элемент последовательности. Аналогично оператору for языка Python, синтаксис таков for X in Y, где Y — это последовательность, а X — это имя переменной, в которую помещается значение текущего элемента. На каждом шагу цикла, шаблонная система выводит всё, что находится между тегами {% for %} и {% endfor %}.
Например, вы можете использовать следующий пример для
отображения списка атлетов, который находится в
athlete_list:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
Добавьте reversed к тегу для обработки списка в обратном порядке:
{% for athlete in athlete_list reversed %}
...
{% endfor %}
Теги {% for %} можно вкладывать друг в друга:
{% for athlete in athlete_list %}
<h1>{{ athlete.name }}</h1>
<ul>
{% for sport in athlete.sports_played %}
<li>{{ sport }}</li>
{% endfor %}
</ul>
{% endfor %}
Ниже показан стандартный способ проверки размера списка перед итерацией по его элементам или вывода отдельного сообщения, в случае пустого списка:
{% if athlete_list %}
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% endfor %}
{% else %}
<p>There are no athletes. Only computer programmers.</p>
{% endif %}
Так как этот способ часто употребляется на практике, тег {% for %} поддерживает необязательный оператор {% empty %}, который позволяет выводить сообщение, в случае пустого списка. Этот пример эквивалентен предыдущему:
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% empty %}
<p>There are no athletes. Only computer programmers.</p>
{% endfor %}
Нет стандартной возможности прекратить цикл до окончания обработки списка. Если вам надо это сделать, создайте переменную, которая будет содержать список только с теми значениями, которые нужны. Аналогично, нет поддержки оператора continue, который бы позволил перейти к обработке следующего элемента списка. (Обратитесь к разделу «Философия и ограничения» для описания причин, которые привели к такому поведению тега.)
Во время каждой итерации {% for %} вы
получаете доступ к шаблонной переменной
forloop. Эта переменная обладает
несколькими атрибутами, которые предоставляют информацию о
текущем цикле:
forloop.counterвсегда содержит целое число, представляющее собой количество выполненных итераций, включая текущую. Отсчёт начинается с единицы, таким образом, во время первой итерации данный атрибут будет иметь значение 1. Пример:{% for item in todo_list %} <p>{{ forloop.counter }}: {{ item }}</p> {% endfor %}forloop.counter0аналогиченforloop.counter, только отсчёт начинается с нуля. То есть, во время первой итерации данный атрибут будет иметь значение 0.forloop.revcounterвсегда содержит целое число, представляющее собой количество оставшихся итераций. Во время первой итерации данный атрибут содержит число, равное количеству итераций цикла, а во время последней итерации — атрибут содержит значение 1.forloop.revcounter0аналогичен атрибутуforloop.revcounter, только отсчёт начинается с нуля. Во время первой итерации данный атрибут содержит число, равное количеству итераций цикла минус единица, а время последней итерации — атрибут содержит значение 0.forloop.firstявляется Boolean и установлен в True только во время первой итерации цикла. Пример использования:{% for object in objects %} {% if forloop.first %}<li class="first">{% else %}<li>{% endif %} {{ object }} </li> {% endfor %}forloop.lastявляется Boolean и установлен в True только во время последней итерации цикла. Пример использования:{% for link in links %}{{ link }} {% if not forloop.last %}|{% endif %} {% endfor %}После обработки данного тега получается примерно такой результат:
Link1 | Link2 | Link3 | Link4Другим примером может быть пример с разделением слов с помощью запятой:
Favorite places: {% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}forloop.parentloopявляется ссылкой на объект forloop родительского цикла, в случае вложенных циклов. Пример:{% for country in countries %} <table> {% for city in country.city_list %} <tr> <td>Country #{{ forloop.parentloop.counter }}</td> <td>City #{{ forloop.counter }}</td> <td>{{ city }}</td> </tr> {% endfor %} </table> {% endfor %}
Эта волшебная переменная forloop доступна
только внутри циклов. После того, как парсер достигнет тега
{% endfor %}, переменная
forloop уничтожается.
Контекст и переменная forloop
Inside the {% for %} block, the existing
variables are moved out of the way to avoid overwriting
the magic forloop variable. Django
exposes this moved context in
forloop.parentloop FIXME. В общем
случае вам не надо беспокоиться об этом, но если вы
будете использовать в блоке переменную
forloop (не смотря на наши
рекомендации не делать так), она будет переименована в
forloop.parentloop на время обработки
блока {% for %}.
Аналогично принятому в HTML или Python, шаблонный язык Django позволяет использовать комментарии. Для определения комментария используйте {# #}:
{# This is a comment #}
Комментарий не будет отображен при обработке шаблона.
Комментарии, использующие данный синтаксис, не могут быть многострочными. Данное ограничение повышает производительность обработки шаблонов. При обработке следующего шаблона комментарий будет отображён как есть (т.е., тег не будет распознан как комментарий):
This is a {# this is not
a comment #}
test.
Если вам необходимо использовать многострочные комментарии, используйте шаблонный тег {% comment %}, вот так:
{% comment %}
This is a
multi-line comment.
{% endcomment %}
Как было описано ранее в этой главе, шаблонные фильтры представляют собой простой способ изменения значения переменных перед их отображением. Фильтры используют символ |:
{{ name|lower }}
Этот код выведет значение переменной {{ name }}, после его обработки фильтром lower, который преобразует буквы текста в нижний регистр.
Фильтры могут подключаться один к другому. Ниже показан пример, который берёт первый элемент списка и преобразовывает его в верхний регистр:
{{ my_list|first|upper }}
Некоторые фильтры принимают аргументы. Аргумент фильтра указывается после двоеточия и всегда в двойных кавычках. Например:
{{ bio|truncatewords:"30" }}
Этот код отобразит первые тридцать слов из переменной
bio.
Далее представлены несколько наиболее важных фильтров. Приложение F FIXME описывает все остальные.
addslashes: Добавляет обратные слеш перед символами: обратный слеш, одинарная или двойная кавычки. Это удобно при включении созданного текста в строку JavaScript.
date: Форматирует вывод объекта date или datetime в соответствии с форматной строкой, переданной в параметре, например:
{{ pub_date|date:"F j, Y" }}Формат аргумента определён в приложении F FIXME.
length: Возвращает длину значения. Для списка возвращается количество его элементов. Для строки — количество символов. (Следует отметить, что этот фильтр работает с любым объектом Python, который знает как определять свою длину, т.е., с любым объектом обладающим методом
__len__().)
| Пред. | Уровень выше | След. |
| Использование шаблонной системы | Начало | Философия и ограничения |
1 comment | Make a comment
forloop.revcounter0 аналогичен атрибуту forloop.revcounter, только отсчёт начинается с нуля.
Думаю правильно будет так:
forloop.revcounter0 аналогичен атрибуту forloop.revcounter, только отсчёт закончится нулем.