Шаблоны — контекст, рендеринг и сокращения

Шаблон – специально подготовленный образец, на основе которого генерируется веб-страница. За работы с шаблонами в Django отвечает система, которую принято называть шаблонизатором.

Такой шаблон представляет собой классический HTML-код, в который добавлены специальные инструкторы шаблонизатора: фильтры, директивы и теги.  Фильтры предназначены для выполнения определенных преобразований данных перед выводом, директивы позволяют вывести какое либо значение, а теги позволяют управлять генерированием содержимого.

По умолчанию шаблонизатор осуществляет поиск шаблонов только в каталогах templates, которые находятся в папках приложений, файлы должны иметь расширение html. Метод поиска можно изменить через настройки.

Приступим к созданию первого шаблона. Для этого в каталоге bboard создадим папку templates, а в ней – вложенный каталог bboar. Перейдя в новую папку, создадим собственный шаблон – файл index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Главная :: Доска объявлений</title>
    </head>
    <body>
        <h1>Объявления</h1>
        {% for bb in bbs %}
        <div>
            <h2>{{ bb.title }}</h2>
            <p>{{ bb.content }}</p>
            <p>{{ bb.published | date: "d.m.Y H:i:s" }}</p>
        </div>
        {% endfor %}
    </body>
</html>

В целом это обычный код HTML, однако присутствуют команды шаблонизатора.

Рассмотрим данный тег:

{% for bb in bbs %}
. . . 
{% endfor %}

Данная конструкция работает аналогично циклу for языка Python – осуществляется перебор последовательности, которая хранится в переменной bbs (она входит в состав контекста текущего шаблона, будет рассмотрена позднее). Очередной элемент присваивается переменной bb, которая используется в теле цикла. В нашем случае переменная bbs хранит набор объявлений, а переменная bb – текущее объявление.

Далее рассмотрим директиву шаблонизатора:

{{ bb.title }}

В ней дается команда извлечь атрибут title объекта, который хранится в переменной bb, и вывести его значение в соответствующее место в коде.

Также используется фильтр date:

<p>{{ bb.published | date: "d.m.Y H:i:s" }}</p>

Он позволяет преобразовать значение атрибута published (временная метка) в определенный формат, который указывается в виде специальной строки после двоеточия. В нашем примере строка задает следующий формат вывода даты: <число>.<месяц цифрой>.<год – четыре цифры> <часы 24-ой формат>:<минуты>:<секунды>.

Контекст, рендеринг и сокращения

Вернемся к модулю views.py приложения bboard и исправим текущий код на следующий:

from django.http import HttpResponse
from django.template import loader

from .models import Bb 
def index(request):
    template = loader.get_template('bboard/index.html')
    bbs = Bb.objects.order_by('-published')
    context = {'bbs': bbs}
    return HttpResponse(template.render(context, request))

В первую очередь загружается шаблон при помощи функции get_template() (входит в состав модуля django.template.loader). Путь к файлу указывается в параметре в виде строки. Данная функция возвращает экземпляр класса Template, который представляет собой шаблон из указанного файла.

Далее формируется контекст шаблона – данные, которые необходимо вывести на сгенерированной HTML-странице. Контекст шаблона должен быть сформирован как обычный словарь Python, элементы которого преобразуются в переменные для использования внутри шаблона. Так, элемент bbs созданного контекста шаблона и содержащий все объявления, преобразуется в переменную bbs, которая и используется для вывода в шаблоне.

Завершающий этап – выполнение рендеринга шаблона (генерация готовой веб-страницы). Для этого вызывается метод render(), который относится к классу Template. Методу передается сформированный ранее контекст шаблона, а также экземпляр класса HttpRequest, который представляет собой клиентский запрос (передается через параметр request). Результат представляет собой готовый к выводу HTML-код, передается конструктору класса HttpResponse для подготовки ответа.

После сохранения обоих файлов можно снова запустить отладочный сервер и оценить полученный результат:

Первая версия контроллера index() использует для рендеринга низкоуровневые инструменты, что заметно усложняет код в целом. Однако Django предоставляет и инструменты более высокого уровня – готовые функции-сокращения (shortcuts). К примеру, функция-сокращение render(), которая входит в состав модуля django.shortcuts, обеспечивает выполнение и загрузки и рендеринга шаблона. Для демонстрации возможности исправим код модуля views.py:

from django.shortcuts import render
from .models import Bb
def index(request):
    bbs = Bb.objects.order_by('-published')
    return render(request, 'bboard/index.html', {'bbs': bbs})

После сохранения файла и обновления страницы видно, что результат выполнения кода аналогичный, однако сам код более компактен.





Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: