В больших проектах часто создается один родительский шаблон base.html для всего сайта и родительские шаблоны для каждого крупного раздела сайта. Все шаблоны разделов наследуют от base.html, и каждая страница сайта наследует от шаблона раздела. При такой структуре вы сможете легко изменять оформление и поведение сайта в целом, любого его раздела или отдельной страницы. Данная конфигурация сильно повышает эффективность работы и стимулирует разработчика к дальнейшему совершенствованию сайта.
Страница со списком тем
Разобравшись с тем, как эффективно организовать построение страниц, мы можем сосредоточиться на следующих двух страницах: списке всех тем и списке записей по одной теме. На странице тем выводится перечень всех тем, созданных пользователями, и это первая страница, на которой нам придется работать с данными.
Схема URL для тем
Сначала нужно определить URL для страницы тем. Обычно в таких случаях выбирается простой фрагмент URL, который отражает суть информации, представленной на странице. Мы воспользуемся словом topics, так что для получения страницы будет использоваться URL http://localhost:8000/topics/. А вот какие изменения следует внести в learning_logs/urls.py:
urls.py
"""Определяет схемы URL для learning_logs."""
...
urlpatterns = [
# Домашняя страница
url(r'^$', views.index, name='index'),
. .# Вывод всех тем.
(1) . .url(r'^topics/$', views.topics, name='topics'),
]
Мы просто добавили topics/ в аргумент регулярного выражения, используемый с URL-адресом домашней страницы (1) . Когда Django проверяет запрашиваемый URL-адрес, эта схема совпадет с любым URL-адресом, который состоит из базового URL-адреса и слова topics. Косую черту в конце можно включить, можно не включать, но после слова topics ничего быть не должно, иначе схема не совпадет. Любой запрос с URL-адресом, соответствующим этой схеме, будет передан функции topics() в views.py.
Представление topics
Функция topics() должна получать данные из базы данных и отправлять их шаблону. Обновленная версия views.py выглядит так:
views.py
from django.shortcuts import render
(1) from .models import Topic
def index(request):
...
(2)def topics(request):
. ."""Выводит список тем."""
(3) . .topics = Topic.objects.order_by('date_added')
(4) . .context = {'topics': topics}
(5) . .return render(request, 'learning_logs/topics.html', context)
Сначала импортируется модель, связанная с нужными данными (1) . Функции topics() необходим один параметр: объект запроса, полученный Django от сервера (2). В точке (3) выдается запрос к базе данных на получение объектов Topic, отсортированных по атрибуту date_added. Полученный итоговый набор сохраняется в topics.
В точке (4) определяется контекст, который будет передаваться шаблону. Контекст представляет собой словарь, в котором ключами являются имена, используемые в шаблоне для обращения к данным, а значениями — данные, которые должны передаваться шаблону. В данном случае существует всего одна пара «ключ—значение», которая содержит набор тем, отображаемых на странице. При построении страницы, использующей данные, функции render() передается переменная context, а также объект request и путь к шаблону (5).
Шаблон topics
Шаблон страницы со списком тем получает словарь context, чтобы шаблон мог использовать данные, предоставленные topics(). Создайте файл с именем topics.html в одном каталоге с index.html. Вывод списка тем в шаблоне осуществляется следующим образом:
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
Topics
(1)
(2) . .{% for topic in topics %}
(3) . .
(4) . .{% empty %}
. .
(5) . .{% endfor %}
?
{% endblock content %}
Сначала тег {% extends %} объявляет о наследовании от base.html, как и в случае с шаблоном index, после чего открывается блок content. Тело страницы содержит маркированный (bulleted) список введенных тем. В стандартном языке HTML маркированный список называется неупорядоченным списком и обозначается тегами
В точке (2) находится другой шаблонный тег, эквивалентный циклу for для перебора списка тем из словаря context. Код, используемый в шаблоне, отличается от Python в нескольких важных отношениях. Python использует отступы для обозначения строк, входящих в тело цикла. В шаблоне каждый цикл for должен снабжаться явным тегом {% endfor %}, обозначающим конец цикла. Таким образом, в шаблонах часто встречаются циклы следующего вида:
{% for элемент in список %}
. .действия для каждого элемента
{% endfor %}