В этой главе вы научились использовать формы для создания новых тем и записей, а также редактирования существующих данных. Далее мы перешли к реализации системы учетных записей. Вы предоставили существующим пользователям возможность начинать и завершать сеанс работы с приложением, а также научились использовать класс Django UserCreationForm для создания новых учетных записей.
После создания простой системы аутентификации и регистрации пользователей вы ограничили доступ пользователей к некоторым страницам; для этого использовался декоратор @login_required. Затем данные были связаны с конкретными пользователями при помощи отношения внешнего ключа. Вы также узнали, как выполнить миграцию базы данных, когда миграция требует ввести данные по умолчанию.
В последней части главы вы узнали, как ограничить состав данных, просматриваемых пользователем, с использованием функций представления. Для чтения соответствующих данных использовался метод filter(), а владелец запрашиваемых данных сравнивался с текущим пользователем.
Не всегда бывает сразу понятно, какие данные должны быть доступны всем пользователям, а какие данные следует защищать, но этот навык приходит с практикой. Решения, принятые нами в этой главе для защиты данных пользователей, наглядно показывают, почему при построении проекта желательно работать в команде: если кто-то просматривает код вашего проекта, это повышает вероятность выявления плохо защищенных областей.
К настоящему моменту мы построили полностью функционирующий проект, работающий на локальной машине. В последней главе мы доработаем оформление приложения Learning Log, чтобы оно выглядело более привлекательно. Также проект будет развернут на сервере, чтобы любой пользователь с доступом к Интернету мог зарегистрироваться и создать учетную запись.
20. Оформление и развертывание приложения
Приложение Learning Log уже вполне работоспособно, но оно не имеет стилевого оформления и работает только на локальной машине. В этой главе мы определим для проекта простое, но профессиональное оформление, а затем развернем его на сервере, чтобы любой желающий мог создать учетную запись.
Для стилевого оформления будет использоваться библиотека Bootstrap — набор инструментов для оформления веб-приложений, с которыми они будут выглядеть профессионально на любых современных устройствах, от большого монитора с плоским экраном до смартфона. Для этого мы воспользуемся приложением django-bootstrap3, а вы заодно потренируетесь в использовании приложений, созданных другими разработчиками Django.
Для развертывания Learning Log будет использоваться Heroku — сайт, позволяющий загрузить ваш проект на один из его серверов, чтобы сделать его доступным для любого пользователя с подключением к Интернету. Также мы начнем пользоваться системой контроля версий Git для отслеживания изменений в проекте.
Когда работа с Learning Log будет завершена, вы будете уметь разрабатывать простые веб-приложения, придавать им качественный внешний вид и развертывать их на работающих серверах. Также по мере накопления опыта вы научитесь пользоваться ресурсами с материалами более высокого уровня.
Оформление приложения Learning Log
До сих пор мы намеренно игнорировали оформление приложения, чтобы сосредоточиться на его функциональности. И это вполне разумный подход к разработке, потому что приложение приносит пользу только в том случае, если оно работает. Конечно, когда приложение начинает работать, оформление выходит на первый план, чтобы пользователи захотели работать с ним.
В этом разделе я кратко опишу приложение django-bootstrap3 и покажу, как интегрировать его в проект и подготовить к развертыванию.
Приложение django-bootstrap3
Для интеграции Bootstrap в наш проект будет использоваться приложение django-bootstrap3. Это приложение загружает необходимые файлы Bootstrap, размещает их в правильных каталогах проекта и предоставляет доступ к стилевым директивам в шаблонах проекта.
Чтобы установить django-bootstrap3, введите следующую команду в активной виртуальной среде:
(ll_env)learning_log$ pip install django-bootstrap3
...
Successfully installed django-bootstrap3
Затем необходимо добавить следующий код для включения django-boostrap3 в список INSTALLED_APPS в файле settings.py:
settings.py
...
INSTALLED_APPS = (
...
'django.contrib.staticfiles',
. .# Сторонние приложения
. .'bootstrap3',
. .
# Мои приложения
'learning_logs',
'users',
)
...
Создайте новую секцию для приложений, созданных другими разработчиками, и включите в нее запись 'bootstrap3'. Обычно приложения должны включаться в INSTALLED_APPS,но для надежности прочитайте инструкции по установке конкретного приложения.
Приложение django-bootstrap3 должно включать jQuery — библиотеку JavaScript, которая содержит некоторые интерактивные элементы, предоставляемые шаблоном Bootstrap. Добавьте следующий код в конец settings.py:
settings.py
...
# Мои настройки
LOGIN_URL = '/users/login/'
# Настройки django-bootstrap3
BOOTSTRAP3 = {
. .'include_jquery': True,
. .}
Этот фрагмент избавляет вас от необходимости загружать библиотеку jQuery и размещать ее в правильном каталоге вручную.
Использование Bootstrap для оформления Learning Log
По сути Bootstrap представляет собой большой набор инструментов стилевого оформления. Также библиотека содержит ряд шаблонов, которые можно применить к проекту для формирования общего стиля. Если вы только начинаете работать с Bootstrap, вам будет намного проще воспользоваться этими шаблонами, чем использовать отдельные инструменты оформления. Чтобы просмотреть шаблоны, предоставляемые Bootstrap, перейдите в раздел Getting Started на сайте http://getbootstrap.com/; прокрутите страницу до заголовка Examples и найдите раздел Navbars in action. Мы воспользуемся шаблоном Static top navbar, который предоставляет простую панель навигации у верхнего края, заголовок страницы и контейнер для ее содержимого.
На рис. 20.1 показано, как будет выглядеть домашняя страница после применения шаблона Bootstrap к base.html и незначительного изменения index.html.
Рис. 20.1. Домашняя страница Learning Log
Теперь вы знаете, к какому результату мы стремимся, и вам будет проще понять дальнейшие пояснения.
Изменение base.html
Шаблон base.html необходимо изменить так, чтобы в нем был задействован шаблон Bootstrap. Новая версия base.html будет представлена в несколько этапов.
Определение заголовков HTML
Первое изменение в base.html: заголовки HTML определяются в файле, чтобы при открытии страницы Learning Log в строке заголовка браузера выводилось имя сайта. Также будут добавлены некоторые требования для использования Bootstrap в шаблонах. Удалите все содержимое base.html и замените его следующим кодом:
base.html
(1) {% load bootstrap3 %}
(2)
(3)
(4)
. .
. .
. .
(5) . .
? . .{% bootstrap_css %}
. .{% bootstrap_javascript %}
?
В точке (1) загружается коллекция шаблонных тегов из django-bootstrap3. Затем файл объявляется как документ HTML (2), написанный на английском языке (3). Файл HTML состоит из двух основных частей, заголовка и тела — заголовок файла начинается в точке (4). Заголовок файла HTML не содержит контента: он всего лишь передает браузеру информацию, необходимую для правильного отображения страницы. В точке (5) включается элемент title страницы; его содержимое будет выводиться в строке заголовка браузера при открытии Learning Log. В точке ? используется один из шаблонных тегов django-bootstrap3, который приказывает Django включить все стилевые файлы Bootstrap. Следующий тег активизирует все интерактивное поведение, которое может использоваться на странице, — например, раздвижные навигационные панели. В точке ? располагается закрывающий тег .
Определение навигационной панели
В верхней части страницы определяется навигационная панель:
...
. .
(1) . .
. .
. . . .
. . . .
. . . .
(4) . . . .
. . . .
. .
. .
Первый элемент — открывающий тег
. Тело файла HTML содержит контент, который будет виден пользователям на странице. В точке (1) элемент(1) . .
. .
(2) . . . .{% block header %}{% endblock header %}
. .
. .
(3) . . . .{% block content %}{% endblock content %}
. .
. .
В точке (1) открывается тег div с классом container. Тег div определяет часть веб-страницы, которая может использоваться для любых целей и может оформляться с применением обрамления, пустого пространства вокруг элемента (полей), пустого пространства между содержимым и границей области (отступов), цветов фона и других стилевых правил. Этот конкретный элемент div выполняет функции контейнера для размещения двух элементов: нового блока с именем header (2) и блока content, использовавшегося в главе 18 (3). Блок header содержит сведения о том, какая информация размещается на странице и что можно сделать на странице. Ему назначается класс page-header, который применяет к блоку набор стилевых правил. Блок content размещается в отдельном элементе div без явного задания стилевых классов.
Загрузив домашнюю страницу Learning Log в браузере, вы увидите профессиональную навигационную панель, изображенную на рис. 20.1. Попробуйте изменить размеры окна, заметно уменьшив его ширину; навигационная панель должна превратиться в кнопку. Щелкните на кнопке, и все ссылки появятся в раскрывающемся списке.
Примечание
Эта упрощенная версия шаблона Bootstrap должна работать в большинстве современных браузеров. В старых браузерах некоторые стили могут отображаться некорректно. Полный шаблон, доступный по адресу http://getbootstrap.com/getting-started/#examples/, будет работать почти во всех существующих браузерах.
Модификация домашней страницы
Изменим домашнюю страницу при помощи нового блока header и другого элемента Bootstrap, так называемого табло (jumbotron) — большого блока, который выдается на общем фоне страницы и может содержать любую информацию на ваше усмотрение. Обычно этот элемент используется на домашних страницах для размещения краткого описания проекта в целом. И раз уж мы занялись домашней страницей, заодно обновим текст сообщения. Файл index.html выглядит так:
index.html
{% extends "learning_logs/base.html" %}
(1) {% block header %}
(2)
. .
Track your learning.
. . . .{% endblock header %}
{% block content %}
(3)
. .Register an account to make
. .your own Learning Log, and list the topics you're learning about.
. .Whenever you learn something new about a topic, make an entry
. .summarizing what you've learned.
{% endblock content %}
В точке (1) мы сообщаем Django о том, что далее следует определение содержимого блока header. В элементе jumbotron (2) размещается краткий подзаголовок Track your learning, который дает посетителям представление о том, что делает Learning Log.
В точке (3) добавляется текст, который поможет сориентироваться неопытным пользователям. Приложение предлагает посетителю создать учетную запись, а также описывает два основных действия — создание новых тем и создание записей по темам. Страница на рис. 20.1 выглядит намного лучше, чем страница нашего проекта с простейшим оформлением.
Оформление страницы входа
Мы усовершенствовали внешний вид страницы входа, но формы входа изменения пока не коснулись. Приведем внешний вид формы в соответствие с остальными элементами страницы:
login.html
{% extends "learning_logs/base.html" %}
(1) {% load bootstrap3 %}
(2){% block header %}
Log in to your account.
{% endblock header %}
{% block content %}
. .
(3)
. .
{% endblock content %}
В точке (1) в шаблон загружаются шаблонные теги bootstrap3. В точке (2) определяется блок header, который описывает, для чего нужна страница. Обратите внимание: блок {% if form.errors %} удален из шаблона; django-bootstrap3 управляет ошибками формы автоматически.
В точке (3) добавляется атрибут class="form", после чего при отображении формы (4) используется шаблонный тег {% bootstrap_form %}; он заменяет тег {{ form.as_p }}, используемый в главе 19. Шаблонный тег {% booststrap_form %} вставляет правила в стиле Bootstrap в отдельные элементы формы при ее построении. В точке (5) открывается шаблонный тег bootstrap3 {% buttons %}, который добавляет стилевое оформление Bootstrap к кнопкам.
На рис. 20.2 показана форма входа так, как она выглядит сейчас. Страница стала намного чище, ее оформление — последовательно, а предназначение — предельно ясно.
Рис. 20.2. Страница входа, оформленная с использованием Bootstrap
Попробуйте выполнить вход с неверным именем пользователя или паролем; вы увидите, что даже сообщения об ошибках следуют тому же стилю оформления и хорошо интегрируются с сайтом в целом.
Оформление страницы new_topic
Приведем остальные страницы к тому же стилю оформления. Следующей будет преобразована страница new_topic:
new_topic.html
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
(1) {% block header %}
Add a new topic:
{% endblock header %}
{% block content %}
. .
(2)
. .
{% endblock content %}
В основном эти изменения аналогичны тем, которые были применены в login.html: мы загружаем bootstrap3 и добавляем блок header с соответствующим сообщением (1) . Затем в тег