Изучаем Python — страница 54 из 61


В этой главе вы научились использовать формы для создания новых тем и записей, а также редактирования существующих данных. Далее мы перешли к реализации системы учетных записей. Вы предоставили существующим пользователям возможность начинать и завершать сеанс работы с приложением, а также научились использовать класс 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) . .Learning Log


? . .{% bootstrap_css %}

. .{% bootstrap_javascript %}


?

В точке (1) загружается коллекция шаблонных тегов из django-bootstrap3. Затем файл объявляется как документ HTML (2), написанный на английском языке (3). Файл HTML состоит из двух основных частей, заголовка и тела — заголовок файла начинается в точке (4). Заголовок файла HTML не содержит контента: он всего лишь передает браузеру информацию, необходимую для правильного отображения страницы. В точке (5) включается элемент title страницы; его содержимое будет выводиться в строке заголовка браузера при открытии Learning Log. В точке ? используется один из шаблонных тегов django-bootstrap3, который приказывает Django включить все стилевые файлы Bootstrap. Следующий тег активизирует все интерактивное поведение, которое может использоваться на странице, — например, раздвижные навигационные панели. В точке ? располагается закрывающий тег .

Определение навигационной панели


В верхней части страницы определяется навигационная панель:

...


. .

(1) . .

Первый элемент — открывающий тег . Тело файла HTML содержит контент, который будет виден пользователям на странице. В точке (1) элемент


(1) . .

. .

. .

(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)

{% csrf_token %}

(4) . .{% bootstrap_form form %}


(5) . .{% buttons %}

. .

. .{% endbuttons %}

. .

. .

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

. . class="form">

. .

{% csrf_token %}

(3) . .{% bootstrap_form form %}

. .

(4) . .{% buttons %}

. .

. .{% endbuttons %}

. .

. .

{% endblock content %}

В основном эти изменения аналогичны тем, которые были применены в login.html: мы загружаем bootstrap3 и добавляем блок header с соответствующим сообщением (1) . Затем в тег

добавляется class="form" (2), {{ form.as_p }} заменяется шаблонным тегом {% bootstrap_form %} (3), а для кнопки отправки данных используется структура bootstrap3 (4). Выполните вход и перейдите к странице new_topic; сейчас она должна быть похожа на страницу входа.

Оформление страницы со списком тем


А теперь позаботимся о том, чтобы страницы для просмотра информации также были выдержаны в том же стиле. Начнем со страницы со списком тем:

topics.html

{% extends "learning_logs/base.html" %}


(1) {% block header %}

Topics

{% endblock header %}

{% block content %}



(3)

Add new topic


{% endblock content %}

Тег {% load bootstrap3 %} не нужен, потому что в этом файле не используются никакие шаблонные теги bootstrap3. Заголовок Topics добавляется в блок header (1) . Каждая тема оформляется как элемент

, чтобы она выводилась чуть более крупным шрифтом на странице (2); то же самое делается со ссылкой добавления новой темы (3).

Оформление записей на странице темы


Страница темы содержит больше контента, чем большинство страниц, поэтому над ней придется потрудиться. Чтобы записи визуально выделялись, мы воспользуемся панелями Bootstrap. Панель представляет собой элемент div с заранее определенным стилем и идеально подходит для отображения записей темы:

topic.html

{% extends 'learning_logs/base.html' %}


(1) {% block header %}

{{ topic }}

{% endblock header %}


{% block content %}

add new entry


{% for entry in entries %}

(2) . .

(3) . .

(4) . . . .

. . . . {{ entry.date_added|date:'M d, Y H:i' }}

(5) . . . .

. . . . . .

. . . . . . edit entry

. . . .

. . . .

. .

? . .

. . . .{{ entry.text|linebreaks }}

. .

. .

{% empty %}

. .There are no entries for this topic yet.

{% endfor %}


{% endblock content %}

Сначала тема размещается в блоке header (1) . Затем удаляется структура неупорядоченного списка, использовавшаяся ранее в этом шаблоне. Вместо того чтобы превращать каждую запись в элемент списка, мы создаем в точке (2) элемент div для панели, который содержит два других вложенных элемента div: panel-heading (3) и panel-body (4). Элемент div с классом panel-heading содержит дату записи и ссылку для ее редактирования. Оба элемента оформлены как элементы

, но мы заключаем ссылку edit_entry в теги , чтобы она была чуть меньше временнуй метки (5).

В точке ? располагается элемент div с классом panel-body, который содержит фактический текст записи. Обратите внимание: код Django для включения информации на страницу вообще не изменился; изменились только элементы, влияющие на внешний вид страницы.

Рис. 20.3. Страница темы с оформлением Bootstrap

На рис. 20.3 изображена страница темы с новым оформлением. Функциональность приложения Learning Log не изменилась, но приложение выглядит более привлекательно и заманчиво для пользователя.

Примечание

Если вы хотите использовать другой шаблон Bootstrap, действуйте в той же последовательности, которая уже использовалась в этой главе. Скопируйте шаблон в base.html и измените элементы, содержащие контент, чтобы шаблон отображал информацию вашего проекта. Затем воспользуйтесь средствами индивидуального стилевого оформления Bootstrap для оформления содержимого каждой страницы.

Упражнения

20-1. Другие формы: мы применили стили Bootstrap к страницам login и add_topic. Внесите аналогичные изменения в другие страницы на базе форм: new_entry, edit_entry и register.

20-2. Стилевое оформление Blog: используйте Bootstrap для стилевого оформления проекта Blog из главы 19.

Развертывание Learning Log