Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Django_-_podrobnoe_rukovodstvo

.pdf
Скачиваний:
330
Добавлен:
01.03.2016
Размер:
4.88 Mб
Скачать

490

Приложение E. Встроенные шаблонные­ теги и фильтры

Как видите, в теге if может присутствовать необязательная часть {% else %}, которая выполняется, когда проверка завершается неудачно.

Внутри тега if можно использовать операторы and и or для комбинирования нескольких проверок, а также not для отрицания последующего условия:

{% if athlete_list and coach_list %} Есть спортсмены и тренеры.

{% endif %}

{% if not athlete_list %} Спортсменов нет.

{% endif %}

{% if athlete_list or coach_list %} Есть спортсмены или тренеры.

{% endif %}

{% if not athlete_list or coach_list %}

Нет спортсменов или есть тренеры (да, перевод булевских выражений на естественный язык звучит ужасно, но тут уж мы не виноваты).

{% endif %}

{% if athlete_list and not coach_list %} Есть спортсмены, но нет ни одного тренера.

{% endif %}

В теге if не допускается употреблять одновременно операторы and и or, потому что порядок их выполнения неоднозначен. Например, такая конструкция недопустима:

{% if athlete_list and coach_list or cheerleader_list %}

Если для формулирования сложного условия необходима комбинация операторов and и or, воспользуйтесь вложенными тегами if. Например:

{% if athlete_list %}

{% if coach_list or cheerleader_list %}

Есть спотсмены и либо тренеры, либо группа поддержки! {% endif %}

{% endif %}

При этом допускается несколько раз употреблять один и тот же логический оператор. Например, такая конструкция допустима:

{% if athlete_list or coach_list or parent_list or teacher_list %}

ifchanged

Проверяет, изменилось ли значение по сравнению с предыдущей итерацией цикла­.

Справочник по встроенным тегам

491

Тег ifchanged употребляется внутри цикла;­ возможные варианты использования:

•• Сравнивает содержимое, предназначенное для вывода, с тем, что было выведено на предыдущей итерации, и производит вывод, только если обнаружены изменения. Например, выведем список дат, печатая месяц, только если он изменился по сравнению с предыдущей датой:

<h1Архив за {{ year }}</h1>

{% for date in days %}

{% ifchanged %}<h3>{{ date|date:”F” }}</h3>{% endifchanged %} <a href=”{{ date|date:”M/d”|lower }}/”>{{ date|date:”j” }}</a>

{% endfor %}

•• Если задана переменная, то проверяет, изменилось ли ее значение. Например, в следующем фрагменте дата выводится при каждой смене, но час печатается, только если изменились одновременно и час, и дата:

{% for date in days %}

{% ifchanged date.date %} {{ date.date }} {% endifchanged %} {% ifchanged date.hour date.date %}

{{ date.hour }} {% endifchanged %}

{% endfor %}

В теге ifchanged может присутствовать необязательная часть {% else %}, которая отображается, если значение не изменилось:

{% for match in matches %}

<div style=”background-color:

{% ifchanged match.ballot_id %} {% cycle red,blue %}

{% else %} grey

{% endifchanged %} “>{{ match }}</div>

{% endfor %}

ifequal

Выводит содержимое блока, если оба аргумента тега равны. Например:

{% ifequal user.id comment.user_id %}

...

{% endifequal %}

Как и в теге {% if %}, может присутствовать необязательная часть {% else %}.

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

492

 

Приложение E. Встроенные шаблонные­ теги и фильтры

 

{%

ifequal user.username “adrian” %}

 

 

...

 

{%

endifequal %}

Аргумент можно сравнивать только с шаблонными­ переменными или строками. Не допускается сравнивать с объектами Python, например, True или False. В случае такой необходимости пользуйтесь тегом if.

ifnotequal

Аналогичен ifequal, но проверяется различие аргументов.

include

Загружает шаблон­ и производит его отображение в текущем контексте. Таким способом можно включать один шаблон­ в другой.

Имя шаблона­ может быть переменной или строковым литералом, заключенным в одиночные или двойные кавычки.

Вследующем примере включается содержимое шаблона­ “foo/bar.html”:

{% include “foo/bar.html” %}

Аздесь включается содержимое шаблона,­ имя которого содержится в переменной template_name:

{% include template_name %}

Отображение включаемого шаблона­ производится в контексте включающего шаблона­. В следующем примере выводится строка “Привет, Джон”:

•• Контекст: переменная person имеет значение “Джон”.

•• Шаблон:­

{% include “name_snippet.html” %}

•• Шаблон­ name_snippet.html:

Привет, {{ person }}

См. также: {% ssi %}.

load

Загружает набор пользовательских шаблонных­ тегов. О библиотеках пользовательских тегов см. главу 9.

now

Выводит текущую дату в соответствии с указанной строкой формата.

Синтаксис определения формата такой же, как в PHP-функции date() (http://php.net/date) с некоторыми дополнениями.

В табл. E.2 показаны все имеющиеся спецификаторы формата.

Справочник по встроенным тегам

493

Таблица E.2. Допустимые спецификаторы формата даты

 

Спецификатор

Описание

Пример вывода

 

 

 

 

 

a

‘a.m.’ или ‘p.m.’ (Формат отличается

‘a.m.’

 

 

от принятого в PHP наличием точек,

 

 

 

в соответствии со стилем агентства

 

 

 

«Ассошиэйтед Пресс»)

 

 

A

‘AM’ или ‘PM’

‘AM’

 

b

Трехбуквенное сокращенное

‘jan’

 

 

название месяца, записанное

 

 

 

строчными буквами

 

BНе реализовано

d

Двузначный день месяца,

От ‘01’ до ‘31’

 

с начальным нулем

 

D

Трехбуквенное сокращенное

‘Fri’

 

название дня недели

 

fВремя в 12-часовом формате с часами ‘1’, ‘1:30’ и минутами. Если количество минут

равно нулю, минуты отбрасываются. Добавлен в Django.

F

Полное название месяца

‘January’

g

Час в 12-часовом формате без

от ‘1’ до ‘12’

 

начального нуля

 

G

Час в 24-часовом формате без

от ‘0’ до ‘23’

 

начального нуля

 

h

Час в 12-часовом формате

от ‘01’ до ‘12’

H

Час в 24-часовом формате

от ‘00’ до ‘23’

i

Минуты

от ‘00’ до ‘59’

IНе реализовано

j

День месяца без начального нуля

от ‘1’ до ‘31’

l

Полное название дня недели

‘Friday’

LБулевский признак високосного года True или False

m

Номер месяца, две цифры

от ‘01’ до ‘12’

 

с начальным нулем

 

M

Трехбуквенное сокращенное

‘Jan’

 

название месяца

 

n

Номер месяца без начального нуля

от ‘1’ до ‘12’

N

Сокращенное название месяца

‘Jan.’, ‘Feb.’,

 

в стиле агентства «Ассошиэйтед

‘March’, ‘May’

 

Пресс». Добавлен в Django

 

 

494

 

Приложение E. Встроенные шаблонные­ теги и фильтры

Таблица E.2. (Продолжение)

 

 

 

Спецификатор

Описание

Пример вывода

 

 

 

 

 

 

O

Разница с Гринвичским временем

‘+0200’

 

 

 

в часах

 

 

 

P

Время в 12-часовом формате

‘1 a.m.’, ‘1:30 p.m.’,

 

 

с часами, минутами и признаком

‘midnight’, ‘noon’,

 

 

‘a.m.’/‘p.m.’, причем число минут

‘12:30 p.m.’

 

 

отбрасывается, если оно равно нулю.

 

 

 

 

Полдень и полночь обозначаются

 

 

 

 

специальными строками ‘midnight’

 

 

 

 

и ‘noon’ соответственно. Добавлено

 

 

 

 

в Django

 

 

 

r

Дата в формате RFC 2822

‘Thu, 21 Dec 2000

 

 

 

16:01:07

+0200’

 

s

Секунды, два знака с начальным

от ‘00’ до ‘59’

 

 

нулем

 

 

 

S

Английское окончание порядкового

‘st’, ‘nd’, ‘rd’, ‘th’

 

 

числительного для номера дня

 

 

 

 

в месяце, две буквы

 

 

 

t

Количество дней в указанном месяце

от 28 до 31

 

T

Часовой пояс, установленный на

‘EST’, ‘MDT’

 

 

данном компьютере

 

 

UНе реализовано

w

Номер дня недели без начального

от ‘0’ (воскресенье)

 

нуля

до ‘6’ (суббота)

W

Номер недели в году по стандарту

от 1 до 53

 

ISO-8601, неделя начинается

 

 

с понедельника

 

y

Двузначный номер года

‘99’

Y

Четырехзначный номер года

‘1999’

z

Номер дня в году

от 0 до 365

ZСмещение часового пояса в секундах. от -43200 до 43200 Смещение для поясов к западу от

UTC отрицательно, к востоку – положительно

Например:

Сейчас {% now “jS F Y H:i” %}

Если в строку формата потребуется добавить символ, совпадающий со спецификатором, его можно экранировать символом обратного слеша. В следующем примере был экранирован символ ‘f’, потому что иначе он

Справочник по встроенным тегам

495

интерпретировался бы как спецификатор для вывода времени. Символ же ‘o’ экранировать не нужно, потому что такого спецификатора фор-

мата не существует:

It is the {% now “jS o\f F” %}

В результате будет выведена строка «It is the 4th of September».

regroup

Перегруппировывает список похожих объектов по общему атрибуту.

Работу этого хитрого тега лучше всего проиллюстрировать на примере. Предположим, что people – список людей, информация о каждом из которых представлена словарем с ключами first_name (имя), last_name (фамилия) и gender (пол):

people = [

{‘first_name’: ‘Джордж’, ‘last_name’: ‘Буш’, ‘gender’: ‘Мужской’}, {‘first_name’: ‘Билл’, ‘last_name’: ‘Клинтон’, ‘gender’: ‘Мужской’}, {‘first_name’: ‘Маргарет’, ‘last_name’: ‘Тэтчер’, ‘gender’: ‘Женский’}, {‘first_name’: ‘Кондолиза’, ‘last_name’: ‘Райс’, ‘gender’: ‘Женский’}, {‘first_name’: ‘Пэт’, ‘last_name’: ‘Смит’, ‘gender’: ‘Неизвестен’},

]

И вы хотите вывести иерархический список, упорядоченный по полу, например:

• Мужской:

•• Джордж Буш

•• Билл Клинтон

• Женский:

•• Маргарет Тэтчер

•• Кондолиза Райс

• Неизвестен:

•• Пэт Смит

Для группировки по полу можно воспользоваться тегом {% regroup %}, как показано ниже:

{% regroup people by gender as gender_list %} <ul>

{% for gender in gender_list %} <li>{{ gender.grouper }} <ul>

{% for item in gender.list %}

<li>{{ item.first_name }} {{ item.last_name }}</li> {% endfor %}

</ul>

</li>

496

Приложение E. Встроенные шаблонные­ теги и фильтры

{% endfor %} </ul>

Разберемся, что здесь происходит. Тег {% regroup %} принимает три аргумента: список, который нужно перегруппировать; атрибут, по которому производится группировка, и имя результирующего списка. В данном случае мы хотим перегруппировать список people по атрибуту gender и назвать результат gender_list.

Тег {% regroup %} порождает список (в нашем случае gender_list) групповых объектов. У каждого группового объекта есть два атрибута:

•• grouper: имя атрибута, по которому образована группа (например, строка “Мужской” или “Женский”).

•• list: список всех элементов этой группы (например, список людей, для которых gender=’Мужской’).

Отметим, что тег {% regroup %} не сортирует входные данные! В нашем примере предполагалось, что список people изначально отсортирован по атрибуту gender. Если бы это было не так, то в результате перегруппировки образовалось бы несколько групп с одним и тем же значением пола. Например, пусть исходный список people выглядит так (обратите внимание, что мужчины не сгруппированы вместе):

people = [

{‘first_name’: ‘Билл’, ‘last_name’: ‘Клинтон’, ‘gender’: ‘Мужской’}, {‘first_name’: ‘Пэт’, ‘last_name’: ‘Смит’, ‘gender’: ‘Неизвестен’}, {‘first_name’: ‘Маргарет’, ‘last_name’: ‘Тэтчер’, ‘gender’: ‘Женский’}, {‘first_name’: ‘Джордж’, ‘last_name’: ‘Буш’, ‘gender’: ‘Мужской’}, {‘first_name’: ‘Кондолиза’, ‘last_name’: ‘Райс’, ‘gender’: ‘Женский’},

]

Если передать такой список people предыдущему фрагменту шаблона­ {% regroup %}, он породит такой результат:

• Мужской:

•• Билл Клинтон

• Неизвестен:

•• Пэт Смит

• Женский:

•• Маргарет Тэтчер

• Мужской:

•• Джордж Буш

• Женский:

•• Кондолиза Райс

Чтобы решить эту проблему, проще всего заранее отсортировать список данных и только потом передавать его в шаблон­.

Справочник по встроенным тегам

497

Есть и другое решение – отсортировать данные прямо в шаблоне­ с помощью фильтра dictsort. Но применимо оно только в случае, когда данные представляют собой список словарей:

{% regroup people|dictsort:”gender” by gender as gender_list %}

spaceless

Удаляет пробельные символы между HTML-тегами (пробелы, символы табуляции и перехода на новую строку). Например:

{% spaceless %} <p>

<a href=”foo/”>Foo</a>

</p>

{% endspaceless %}

Врезультате получится такая HTML-разметка:

<p><a href=”foo/”>Foo</a></p>

Удаляются только пробельные символы между тегами, но не между тегами и текстом. В следующем примере пробелы, окружающие слово Привет, не удаляются:

{% spaceless %} <strong>

Привет

</strong>

{% endspaceless %}

ssi

Выводит содержимое указанного файла на страницу.

Как и тег include, {% ssi %} включает содержимое другого файла, заданного абсолютным путем:

{% ssi /home/html/ljworld.com/includes/right_generic.html %}

Если присутствует необязательный параметр “parsed”, то содержимое включаемого файла обрабатывается как код шаблона­ в текущем контексте:

{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}

Отметим, что при использовании тега {% ssi %} необходимо определить в конфигурационном файле Django параметр ALLOWED_INCLUDE_ROOTS для пущей безопасности.

См. также {% include %}.

templatetag

Выводит один из синтаксических элементов шаблонных­ тегов.

498

Приложение E. Встроенные шаблонные­ теги и фильтры

Поскольку в системе­ шаблонов­ нет механизма экранирования, то для буквального вывода синтаксических элементов шаблона­ приходится использовать тег {% templatetag %}.

Все допустимые аргументы этого тега перечислены в табл. E.3.

Таблица E.3. Аргументы тега templatetag

Аргумент

Выводит

 

 

openblock

{%

closeblock

%}

openvariable

{{

closevariable

}}

openbrace

{

closebrace

}

opencomment

{#

closecomment

#}

 

 

url

Возвращает абсолютный URL (то есть URL без доменного имени), со-

ответствующий указанной функции представления, с необязательными параметрами. Таким способом можно формировать ссылки, не зашивая их URL-адреса в шаблоны­ и, следовательно, не нарушая прин-

цип DRY:

{% url path.to.some_view arg1,arg2,name1=value1 %}

Первый аргумент – это путь к функции представления в виде package. package.module.function. Все остальные аргументы необязательны. Если они присутствуют, то должны разделяться запятыми и будут использоваться как позиционные и именованные параметры в строке запроса. Все аргументы, указанные в конфигурации URL, должны быть заданы обязательно.

Пусть, например, имеется представление app_views.client, для которого в образце URL указан идентификатор клиента (здесь client() – метод, определенный в файле представления app_views.py). Этот образец мог бы выглядеть так:

(‘^client/(\d+)/$’, ‘app_views.client’)

Если конфигурация URL этого приложения включена в конфигурацию URL всего проекта:

(‘^clients/’, include(‘project_name.app_name.urls’))

Справочник по встроенным фильтрам

499

то в шаблоне­ можно создать ссылку на представление следующим образом:

{% url app_views.client client.id %}

Этот тег выведет строку /clients/client/123/.

widthratio

При создании столбчатых диаграмм и других подобных вещей этот тег вычисляет отношение данного значения к максимальному, а затем умножает результат на константу. Например:

<img src=”bar.gif” height=”10” width=”{% widthratio this_value max_value 100 %}” />

Если this_value равно 175, а max_value равно 200, то ширина изображения

впримере выше составит 88 пикселов (так как 175 / 200 = 0.875, 0.875 * 100 = 87.5, что после округления дает 88).

with

Кэширует составную переменную под простым именем. Это полезно, когда требуется вызвать дорогостоящий метод (например, несколько раз обращающийся к базе данных). Например:

{% with business.employees.count as total %} {{ total }} employee{{ total|pluralize }}

{% endwith %}

Кэшированная переменная (в данном примере total) существует только в блоке между тегами {% with %} и {% endwith %}.

Справочник по встроенным фильтрам add

Прибавляет аргумент к значению, например:

{{ value|add:”2” }}

Если value равно 4, то получится 6.

addslashes

Вставляет символы слеша перед кавычками. Полезно, например, для экранирования строк в формате CSV.

capfirst

Переводит первый символ значения в верхний регистр.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]