Главная | Архив новостей | Общение | Площадка | Примеры OpenID
Хостинг Django от «Джино»
Оглавление

Основные шаблонные теги и фильтры

Как мы уже говорили ранее, шаблонная система поставляется со встроенными тегами и фильтрами. Следующие разделы описывают основные теги и шаблоны.

Теги

if/else

Тег {% 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 %}

Теги {% if %} не позволяют объединять and и or в одном теге, потому что порядок логики будет двусмысленным. Пример с ошибкой:

{% 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 %}

Тега {% 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 %} позволяет обработать каждый элемент последовательности. Аналогично оператору 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 %}.

ifequal/ifnotequal

Шаблонная система Django умышленно создана в виде неполноценного языка программирования и, следовательно, не позволит вам выполнить операторы языка Python. (Более подробно данный аспект рассмотрен в разделе «Философия и ограничения» данной главы.) Тем не менее, сравнение двух значений и отображение некой информации в случае равенства является достаточно общим требованием к шаблонам. И Django предоставляет тег {% ifequal %} для решения данной задачи.

Тег {% ifequal %} сравнивает два значения и отображает всё, что находится между {% ifequal %} и {% endifequal %}, если эти значения равны.

Данный пример сравнивает шаблонные переменные user и currentuser:

{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}

Аргументами могут служить строки (вбитые в шаблон), ограниченные одинарными или двойными кавычками, вот пример:

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% endifequal %}

{% ifequal section "community" %}
    <h1>Community</h1>
{% endifequal %}

Аналогично {% if %}, тег {% ifequal %} поддерживает необязательный тег {% else %}:

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

В качестве аргументов тега разрешено использовать только переменные, строки, целые и десятичные числа. Ниже показаны примеры правильного использования:

{% ifequal variable 1 %}
{% ifequal variable 1.23 %}
{% ifequal variable 'foo' %}
{% ifequal variable "foo" %}

Любые другие типы переменных, подобных словарям, спискам или логическим значениям не могут быть использованы в {% ifequal %}. Ниже показаны примеры неправильного использования:

{% ifequal variable True %}
{% ifequal variable [1, 2, 3] %}
{% ifequal variable {'key': 'value'} %}

Если вам требуется проверить соответствие чего-либо логическому значению, используйте тег {% if %} вместо {% ifequal %}.

Комментарии

Аналогично принятому в 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__().)


Увидели ошибку?
Выделите её мышкой и нажмите
Ctrl-Enter
Обработано:
504 49 130 71

Версия книги
1.0 2.0
Версия 2.0 в процессе перевода!

Мой луч
Многообразие света

Полезное
Актуальные вакансии, Python работа для python-разработчиков.


Скачать в формате
CHM от 2 сентября

Заказать PDF файл можно через почту, чат, джаббер. Всего 2WMZ. Содержимое точно соответствует содержимому сайта.
Чем чаще заказываете — тем больше перевожу.

Русская группа

на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!
R130494980980
Z425285133788
E112528079659
U327380922061

Книга помогла реализовать:
Проект «Мой луч»
АРМ УФМС.


Мой вебсайт стоит666 337,31 руб

© 2008-2009 Ruslan Popov @ gmail.com Powered by Django 1.1 beta 1 SVN-11114
Главная | Архив новостей | Общение | Площадка | Примеры OpenID