Изучаем Python. Программирование игр, визуализация данных, веб-приложения

Мэтиз Эрик

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) элемент

 

Определение основного раздела страницы

Оставшаяся часть base.html содержит основной контент страницы:

...

(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 %}

    {% for topic in topics %}

  • (2) . . . .

    . . . . {{ topic }}

    . . . .

  • {% empty %}

  • No topics have been added yet.
  • {% endfor %}

(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

После того как проекту был придан профессиональный вид, мы развернем его на реальном сервере, чтобы любой пользователь с подключением к Интернету мог работать с приложением. Мы воспользуемся Heroku — веб-платформой, позволяющей управлять развертыванием веб-приложений.

Процесс для системы Windows несколько отличается от процесса в Linux и OS X. Если вы работаете в Windows, обращайте внимание на врезки, указывающие, какие изменения следует внести в вашей системе.

 

Создание учетной записи Heroku

Чтобы создать учетную запись, откройте сайт https://heroku.com/ и щелкните на ­одной из регистрационных ссылок. Учетные записи создаются бесплатно, и Heroku предоставляет бесплатный уровень для тестирования проектов в реальных условиях.

Примечание

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

 

Установка инструментария Heroku Toolbelt

Чтобы развернуть проект на серверах Heroku и управлять им, вам понадобятся инструменты из пакета Heroku Toolbelt. Чтобы установить новейшую версию Heroku Toolbelt, откройте сайт https://toolbelt.heroku.com/ и выполните указания для своей операционной системы. В них содержится либо однострочная терминальная команда, либо программа установки, которую вы можете загрузить и запустить.

 

Установка необходимых пакетов

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

(ll_env)learning_log$ pip install dj-database-url

(ll_env)learning_log$ pip install dj-static

(ll_env)learning_log$ pip install static3

(ll_env)learning_log$ pip install gunicorn

Обязательно вводите команды по одной, чтобы вы знали, если при установке какого-либо пакета возникнет проблема. Пакет dj-database-url помогает Django взаимодействовать с базой данных, используемой Heroku, пакеты dj-static и static3 позволяют Django правильно управлять статическими файлами, а gunicorn — сервер, способный предоставлять доступ к приложениям в реальной среде. (Статические файлы содержат стилевые правила и файлы JavaScript.)

Примечание

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

 

Создание списка пакетов с файлом requirements.txt

Heroku необходимо знать, от каких пакетов зависит наш проект, поэтому мы воспользуемся pip для построения файла со списком. Оставаясь в активной виртуальной среде, введите следующую команду:

(ll_env)learning_log$ pip freeze > requirements.txt

Команда freeze приказывает pip записать имена всех пакетов, в настоящее время установленных в системе, в файл requirements.txt. Откройте файл requirements.txt и просмотрите пакеты и номера версий, установленных в вашей системе (возможно, пользователи Windows не увидят какие-то строки):

requirements.txt

Django==1.8.4

dj-database-url==0.3.0

dj-static==0.0.6

django-bootstrap3==6.2.2

gunicorn==19.3.0

static3==0.6.1

Приложение Learning Log уже зависит от шести разных пакетов с конкретными номерами версий, поэтому для его правильной работы требуется конкретная конфигурация среды. При развертывании Learning Log Heroku устанавливает все пакеты, перечисленные в requirements.txt, и создает среду с теми же пакетами, которые мы используем локально. По этой причине разработчик может быть уверен в том, что развернутый проект будет работать точно так же, как в его локальной системе. Вы поймете, насколько это полезно, когда начнете строить и вести в своей системе несколько разных проектов.

Затем необходимо добавить в список пакет psycopg2, который помогает Heroku управлять базой данных. Откройте файл requirements.txt и добавьте строку psycopg2>=2.6.1. Эта строка устанавливает версию 2.6.1 пакета psycopg2 (или более новую версию, если она доступна):

requirements.txt

Django==1.8.4

dj-database-url==0.3.0

dj-static==0.0.6

django-bootstrap3==6.2.2

gunicorn==19.3.0

static3==0.6.1

psycopg2>=2.6.1

Если какие-либо пакеты не установлены в вашей системе, добавьте их. В итоге ваш файл requirements.txt должен включать каждый из приведенных выше пакетов. Если пакет входит в список вашей системы, но номер версии отличается от приведенной, оставьте версию вашей системы.

Примечание

Если вы работаете в системе Windows, убедитесь в том, что ваша версия requirements.txt соответствует приведенному списку, — независимо от того, какие пакеты вам удалось установить в вашей системе.

 

Назначение исполнительной среды Python

Если вы не укажете версию Python, то Heroku будет использовать собственную версию Python по умолчанию. Убедитесь в том, что Heroku использует ту же версию Python, которая используется у вас. В активной виртуальной среде введите команду python --version:

(ll_env)learning_log$ python --version

Python 3.5.0

В этом примере я использую Python 3.5.0. Создайте новый файл с именем runtime.txt в одном каталоге с файлом manage.py и введите следующую команду:

runtime.txt

python-3.5.0

Этот файл должен содержать одну строку с версией Python, заданной точно в показанном формате: python в нижнем регистре, затем дефис и номер версии из трех частей.

Примечание

Если вы получите сообщение об ошибке, в котором сказано, что запрашиваемая исполнительная среда Python недоступна, откройте страницу https://devcenter.heroku.com/ и щелкните на ссылке Python, затем найдите ссылку Specifying a Python Runtime. Просмотрите текст статьи, найдите доступные варианты исполнительной среды и выберите тот вариант, который ближе всего к вашей версии Python.

 

Изменение файла settings.py для Heroku

Затем в конец файла settings.py необходимо добавить раздел для определения настроек, предназначенных конкретно для среды Heroku:

settings.py

...

# Настройки для django-bootstrap3

BOOTSTRAP3 = {

'include_jquery': True,

}

# Настройки Heroku

(1) if os.getcwd() == '/app':

(2) . .import dj_database_url

. .DATABASES = {

. . . .'default': dj_database_url.config(default='postgres://localhost')

. .}

. .

. .# Поддержка заголовка 'X-Forwarded-Proto' для request.is_secure().

(3) . .SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

. .

. .# Разрешены все заголовки хостов.

(4) . .ALLOWED_HOSTS = ['*']

. .# Конфигурация статических ресурсов

(5) . .BASE_DIR = os.path.dirname(os.path.abspath(__file__))

. .STATIC_ROOT = 'staticfiles'

. .STATICFILES_DIRS = (

. . . .os.path.join(BASE_DIR, 'static'),

. .)

В точке (1) используется функция getcwd(), которая возвращает текущий рабочий каталог, из которого был запущен файл. В схеме развертывания Heroku таким каталогом всегда является /app. При локальном развертывании каталог обычно совпадает с именем папки проекта (learning_log в нашем случае). Проверка if гарантирует, что настройки в этом блоке будут применяться только при развертывании проекта в Heroku. Такая структура позволяет создать один файл настроек, который подойдет как для локальной среды разработки, так и для развертывания на сервере.

В точке (2) импортируется модуль dj_database_url, упрощающий настройку базы данных в Heroku. Heroku использует PostgreSQL (или Postgres) — более мощную базу данных, чем SQLite; эти параметры настраивают проект для работы с Postgres в среде Heroku. Остальные настройки обеспечивают поддержку запросов HTTPS (3), правильный доступ к проекту с URL Heroku (4) и правильное размещение статических файлов на Heroku (5).

 

Создание файла Procfile для запуска процессов

Файл Procfile сообщает Heroku, какие процессы должны запускаться для правильной работы проекта. Это однострочный файл, который должен быть сохранен под именем Procfile (символ P верхнего регистра, без расширения) в одном каталоге с файлом manage.py. Содержимое Procfile выглядит так:

Procfile

web: gunicorn learning_log.wsgi --log-file -

Эта строка приказывает Heroku использовать для приложения сервер gunicorn, а при запуске приложения загрузить настройки из файла learning_log/wsgi.py. Флаг log-file сообщает Heroku, какие события должны регистрироваться в журнале.

 

Изменение файла wsgi.py для Heroku

Также необходимо внести изменения в файл wsgi.py для Heroku, потому что конфигурация для Heroku несколько отличается от той, которая использовалась ранее:

wsgi.py

...

import os

from django.core.wsgi import get_wsgi_application

from dj_static import Cling

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "learning_log.settings")

application = Cling(get_wsgi_application())

Мы импортируем приложение Cling, упрощающее организацию доступа к статическим файлам, и используем его для запуска приложения. Этот код также будет работать локально, так что помещать его в блок if не нужно.

 

Создание каталога для статических файлов

В среде Heroku Django собирает все статические файлы и размещает их в одном месте для эффективного управления. Для этих статических файлов мы создадим специальный каталог. В каталоге learning_log, с которыми работали ранее, находится другой каталог с именем learning_log. В этом вложенном каталоге создайте новый подкаталог с именем static; таким образом, полный путь имеет вид learning_log/learning_log/static/. Также необходимо создать временный файл-«заполнитель» в этом каталоге, потому что при загрузке на Heroku пустые каталоги не включаются в проект. Создайте в каталоге static/ файл с именем placeholder.txt:

placeholder.txt

Этот файл необходим для включения в проект каталога learning_log/static/.

Django собирает статические файлы и помещает их в каталог learning_log/static/.

В этом тексте нет ничего особенного; он просто напоминает, почему этот файл был включен в проект.

 

Локальное использование сервера gunicorn

Если вы используете Linux или OS X, вы можете попробовать использовать сервер gunicorn локально, прежде чем развертывать его на сервере Heroku. В активной виртуальной среде выполните команду heroku local, чтобы запустить процессы, определенные в Procfile:

(ll_env)learning_log$ heroku local

Installing Heroku Toolbelt v4... done

...

forego | starting web.1 on port 5000

(1) web.1 | [2015-08-13 22:00:45 -0800] [12875] [INFO] Starting gunicorn 19.3.0

(2)web.1 | [2015-08-13 22:00:45 -0800] [12875] [INFO] Listening at:

. .http://0.0.0.0:5000 (12875)

(3)web.1 | [2015-08-13 22:00:45 -0800] [12878] [INFO] Booting worker with pid: 12878

При первом выполнении heroku local будет установлен набор пакетов из Heroku Toolbelt. Из выходных данных видно, что в приведенном примере сервер gunicorn был запущен с идентификатором процесса 12875 (1) . В точке (2) gunicorn прослушивает запросы на порте 5000. Кроме того, gunicorn запускает рабочий процесс (12878), который будет помогать в обслуживании запросов (3).

Откройте адрес http://localhost:5000/ и убедитесь в том, что все работает; домашняя страница Learning Log должна выглядеть так же, как она выглядит при использовании сервера Django (runserver). Нажмите Ctrl+C, чтобы остановить процессы, запущенные командой heroku local. При локальной разработке продолжайте использовать runserver.

Примечание

В системе Windows gunicorn работать не будет; пропустите этот шаг, если вы используете Windows. Это не повлияет на возможность развертывания проекта в Heroku.

 

Использование Git для управления файлами проекта

Если вы дочитали главу 17, то вы уже знаете, что Git — программа контроля версий, которая позволяет создать «мгновенный снимок» состояния кода проекта при реализации каждой новой функции. Это позволяет легко вернуться к последнему работоспособному состоянию проекта при возникновении каких-либо проблем (например, если в ходе работы над новой функцией была случайно внесена ошибка).

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

 

Установка Git

Git входит в инструментарий Heroku Toolbelt, так что пакет Git уже должен быть установлен в вашей системе. Однако система Git будет недоступна в терминальных окнах, которые были открыты перед установкой Heroku Toolbelt, поэтому откройте новое терминальное окно и введите команду git --version:

(ll_env)learning_log$ git --version

git version 2.5.0

Если вы получите сообщение об ошибке, обращайтесь к инструкциям по установке Git в приложении Г.

 

Настройка Git

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

(ll_env)learning_log$ git config --global user.name "ehmatthes"

(ll_env)learning_log$ git config --global user.email "[email protected]"

Если вы забудете об этом шаге, Git запросит у вас эту информацию при первом закреплении.

 

Игнорирование файлов

Нам не нужно, чтобы система Git отслеживала все файлы в проекте, поэтому мы прикажем Git игнорировать некоторые файлы. Создайте файл с именем .gitignore в папке с файлом manage.py. Обратите внимание: имя файла начинается с точки, а файл не имеет расширения. Содержимое .gitignore выглядит так:

.gitignore

ll_env/

__pycache__/

*.sqlite3

Мы приказываем Git игнорировать весь каталог ll_env, потому что мы можем автоматически воссоздать его в любой момент. Также в системе контроля не отслеживается каталог __pycache__ с файлами .pyc, которые создаются автоматически, когда Django выполняет файлы .py. Мы не отслеживаем изменения в локальной базе данных, потому что так поступать вообще нежелательно: если на сервере будет использоваться SQLite, вы можете случайно переписать «живую» базу данных локальной тестовой базой данных при отправке проекта на сервер.

Примечание

Если вы используете Python 2.7, замените __pycache__ на *.pyc, потому что Python 2.7 не создает каталог __pycache__.

 

Закрепление состояния проекта

Чтобы инициализировать репозиторий Git для Learning Log, добавьте все необходимые файлы в репозиторий и закрепите исходное состояние проекта. Вот как это делается:

(1) (ll_env)learning_log$ git init

Initialized empty Git repository in /home/ehmatthes/pcc/learning_log/.git/

(2)(ll_env)learning_log$ git add .

(3)(ll_env)learning_log$ git commit -am "Ready for deployment to heroku."

[master (root-commit) dbc1d99] Ready for deployment to heroku.

43 files changed, 746 insertions(+)

create mode 100644 .gitignore

create mode 100644 Procfile

--snip--

create mode 100644 users/views.py

(4)(ll_env)learning_log$ git status

# On branch master

nothing to commit, working directory clean

(ll_env)learning_log$

В точке (1) вводится команда git init, которая инициализирует пустой репозиторий в каталоге, содержащем Learning Log. В точке (2) команда git add. добавляет все файлы (кроме игнорируемых) в репозиторий (не забудьте точку). В точке (3) вводится команда git commit -am сообщение: флаг -a приказывает Git включить все измененные файлы в закрепленное состояние, а флаг -m приказывает Git сохранить сообщение в журнале.

Вывод команды git status (4) сообщает, что текущей является главная ветвь, а рабочий каталог пуст. Этот статус должен выводиться каждый раз, когда вы отправляете свой проект на Heroku.

 

Отправка проекта

Наконец-то все готово для отправки проекта на сервер Heroku. В активном терминальном сеансе введите следующие команды:

(1) (ll_env)learning_log$ heroku login

Enter your Heroku credentials.

Email: [email protected]

Password (typing will be hidden):

Logged in as [email protected]

(2)(ll_env)learning_log$ heroku create

Creating afternoon-meadow-2775... done, stack is cedar-14

https://afternoon-meadow-2775.herokuapp.com/ |

. .https://git.heroku.com/afternoon-meadow-2775.git

Git remote heroku added

(3)(ll_env)learning_log$ git push heroku master

...

remote: -----> Launching... done, v6

(4)remote: . . . .https://afternoon-meadow-2775.herokuapp.com/ deployed to Heroku

remote: Verifying deploy.... done.

To https://git.heroku.com/afternoon-meadow-2775.git

bdb2a35..62d711d master -> master

(ll_env)learning_log$

Сначала войдите на сервер Heroku в терминальном сеансе с именем пользователя и паролем, использованными при создании учетной записи на https://heroku.com/ (1) . Затем прикажите Heroku построить пустой проект (2). Heroku генерирует имя, состоящее из двух слов и числа; позднее вы сможете его изменить. Затем вводится команда git push heroku master (3), которая приказывает Git отправить главную ветвь проекта в репозиторий, только что созданный Heroku. После этого Heroku строит проект на своих серверах с использованием этих файлов. В точке (4) указывается URL, который будет использоваться для обращения к развернутому проекту.

После ввода этих команд проект развернут, но еще не настроен полностью. ­Чтобы проверить, что серверный процесс был запущен правильно, введите команду heroku ps:

(ll_env)learning_log$ heroku ps

(1) Free quota left: 17h 40m

(2)=== web (Free): `gunicorn learning_log.wsgi __log-file -`

web.1: up 2015/08/14 07:08:51 (~ 10m ago)

(ll_env)learning_log$

В выходных данных указано, сколько еще времени проект может оставаться активным на протяжении следующих 24 часов (1) . На момент написания книги Heroku позволяет бесплатно развернутым проектам оставаться активными до 18 часов за 24-часовой период. При нарушении этого лимита отображается стандартная серверная страница ошибки; вскоре мы изменим ее. В точке (2) запускается процесс, определенный в Procfile.

Теперь мы можем открыть приложение в браузере командой heroku open:

(ll_env)learning_log$ heroku open

Opening afternoon-meadow-2775... done

Команда избавляет вас от необходимости открывать браузер и вводить URL, который вы получили от Heroku, но при желании сайт можно открыть и так. Вы увидите домашнюю страницу Learning Log с правильным оформлением. Впрочем, с приложением еще работать нельзя, потому что база данных не подготовлена.

Примечание

Процесс развертывания приложений на серверах Heroku время от времени изменяется. Если у вас возникнут неразрешимые проблемы, обращайтесь к документации Heroku за помощью. Откройте страницу https://devcenter.heroku.com/ и щелкните на ссылке Python, затем найдите ссылку Getting Started with Django. Если вы не понимаете то, что там написано, обратитесь к рекомендациям в приложении В.

 

Подготовка базы данных в Heroku

Вы должны выполнить команду migrate, чтобы подготовить базу данных и применить все миграции, сгенерированные в ходе разработки. Для выполнения команд Django и Python в проектах Heroku используется команда heroku run. Пример выполнения команды migrate в среде разработки Heroku:

(1) (ll_env)learning_log$ heroku run python manage.py migrate

(2)Running `python manage.py migrate` on afternoon-meadow-2775... up, run.2435

...

(3)Running migrations:

...

Applying learning_logs.0001_initial... OK

Applying learning_logs.0002_entry... OK

Applying learning_logs.0003_topic_user... OK

Applying sessions.0001_initial... OK

(ll_env)learning_log$

Сначала мы вводим команду heroku run python manage.py migrate (1) . Heroku создает терминальный сеанс для выполнения команды migrate (2). В точке (3) Django применяет миграции по умолчанию, а также миграции, сгенерированные в ходе разработки Learning Log.

Теперь при обращении к развернутому приложению вы сможете использовать его так же, как это делалось в локальной системе. Однако при этом вы не увидите никакие данные, введенные при локальном развертывании, потому что мы не скопировали данные на сервер. Это обычная практика: локальные данные почти никогда не копируются на сервер, потому что они чаще всего являются тестовыми.

Если вы перешлете ссылку на Heroku, получатель сможет работать с вашей версией приложения Learning Log. В следующем разделе мы выполним еще несколько операций, чтобы завершить процесс развертывания и подготовиться к дальнейшей разработке Learning Log.

 

Доработка развернутого приложения

В этом разделе мы доработаем развернутое приложение и создадим суперпользователя (так же, как это было сделано в локальной версии). Заодно мы повысим уровень защиты проекта, переведя настройку отладочного режима DEBUG в состояние False, чтобы пользователи не получали в сообщениях об ошибке дополнительной информации, которая может использоваться для проведения атак на сервер.

 

Создание суперпользователя в Heroku

Вы уже видели, что для выполнения одиночных команд может использоваться команда heroku run. Однако команды также можно выполнять, открыв терминальный сеанс Bash при подключении к серверу Heroku командой heroku run bash. Bash — язык, который работает во многих терминалах Linux. Мы используем терминальный сеанс Bash для создания суперпользователя, чтобы иметь возможность обратиться к административному сайту в развернутом приложении:

(ll_env)learning_log$ heroku run bash

Running `bash` on afternoon-meadow-2775... up, run.6244

(1) ~ $ ls

learning_log learning_logs manage.py Procfile requirements.txt runtime.txt

users

staticfiles

(2)~ $ python manage.py createsuperuser

Username (leave blank to use 'u41907'): ll_admin

Email address:

Password:

Password (again):

Superuser created successfully.

(3)~ $ exit

exit

(ll_env)learning_log$

В точке (1) команда ls выводит информацию о файлах и каталогах, существующих на сервере; это те же файлы, которые присутствуют в нашей локальной системе. В этой файловой системе можно перемещаться так же, как и в любой другой.

Примечание

Пользователи Windows должны использовать те же команды (например, ls вместо dir), потому что они работают с терминалом Linux через удаленное подключение.

В точке (2) выполняется команда создания суперпользователя. Она выдает тот же вывод, который был получен в локальной системе при создании суперпользователя в главе 18. После того как создание суперпользователя в терминальном сеансе будет завершено, введите команду exit для возвращения к терминальному сеансу локальной системы (3).

Теперь вы можете добавить /admin/ в конец URL-адреса развернутого приложения, чтобы войти на административный сайт. У меня этот URL-адрес имеет вид https://afternoon-meadow-2775.herokuapp.com/admin/.

Если другие пользователи уже начали работать с вашим проектом, учтите, что вам будут доступны все их данные! Относитесь к конфиденциальности серьезно, и пользователи начнут доверять вам свои данные.

 

Создание удобного URL-адреса на Heroku

Вероятно, вы бы предпочли использовать более удобные и запоминающиеся URL-адреса, чем https://afternoon-meadow-2775.herokuapp.com/. Чтобы переименовать приложение, достаточно одной команды:

(ll_env)learning_log$ heroku apps:rename learning-log

Renaming afternoon-meadow-2775 to learning-log... done

https://learning-log.herokuapp.com/ | https://git.heroku.com/learning-log.git

Git remote heroku updated

(ll_env)learning_log$

Имя может содержать буквы, цифры и дефисы и выбирается произвольно (при условии, что никто другой еще не занял это имя). Развернутая версия теперь доступна по адресу https://learning-log.herokuapp.com/. По предыдущему URL-адресу проект теперь недоступен; команда apps:rename полностью перемещает проект на новый URL-адрес.

Примечание

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

 

Безопасность проекта

В текущем варианте развертывания проекта существует одна очевидная проблема: настройка DEBUG=True в файле settings.py, включающая вывод отладочных сообщений при возникновении ошибок. Страницы ошибок Django предоставляют критическую отладочную информацию при разработке проекта, но они также дают слишком много информации хакерам, если оставить их включенными на рабочем сервере. Также необходимо проследить за тем, чтобы никто не мог получать информацию или перенаправлять запросы, выдавая себя за хост проекта.

Изменим файл settings.py, чтобы сообщения об ошибках выводились локально, но не в развернутой версии:

settings.py

...

# Настройки Heroku

if os.getcwd() == '/app':

...

# Поддержка заголовка 'X-Forwarded-Proto' для request.is_secure().

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

. .

. .# Хостом проекта может быть только Heroku.

(1) . .ALLOWED_HOSTS = ['learning-log.herokuapp.com']

(2) . .DEBUG = False

# Конфигурация статических ресурсов.

...

Необходимо внести только два изменения: в точке (1) изменяется настройка ALLOWED_HOSTS, чтобы хостом проекта мог быть только сервер Heroku. Используйте имя своего приложения — сгенерированное Heroku (как afternoon-meadow-2775.herokuapp.com в нашем примере) или выбранное вами. В точке (2) переменной DEBUG присваивается значение False, чтобы при возникновении ошибок не раскрывалась конфиденциальная информация.

 

Закрепление и отправка изменений

Теперь изменения, внесенные в settings.py, необходимо закрепить в репозитории Git, а затем отправить их на Heroku. Следующий терминальный сеанс показывает, как это делается:

(1) (ll_env)learning_log$ git commit -am "Set DEBUG=False for Heroku."

[master 081f635] Set DEBUG=False for Heroku.

1 file changed, 4 insertions(+), 2 deletions(-)

(2)(ll_env)learning_log$ git status

# On branch master

nothing to commit, working directory clean

(ll_env)learning_log$

Мы вводим команду git commit с коротким, но содержательным сообщением (1) . Напомню, что флаг -am обеспечивает закрепление всех изменившихся файлов и регистрацию сообщения в журнале. Git видит, что изменился один файл, и закрепляет изменение в репозитории.

В точке (2) из статусной информации видно, что мы работаем с главной ветвью репозитория, а новые изменения для закрепления отсутствуют. Очень важно проверять статусную информацию перед отправкой на Heroku. Если вы не видите сообщение, значит, некоторые изменения не были закреплены, и они не будут отправлены на сервер. Попробуйте снова ввести команду commit, а если вы не уверены в том, как решить проблему, — прочитайте приложение Г, чтобы лучше понять, как работать с Git.

Теперь отправим обновленный репозиторий на Heroku:

(ll_env)learning_log$ git push heroku master

...

remote: -----> Python app detected

remote: -----> Installing dependencies with pip

...

remote: -----> Launching... done, v8

remote: . . . .https://learning-log.herokuapp.com/ deployed to Heroku

remote: Verifying deploy.... done.

To https://git.heroku.com/learning-log.git

4c9d111..ef65d2b master -> master

(ll_env)learning_log$

Heroku видит, что репозиторий обновился, и заново строит проект, чтобы все изменения были учтены. База данных при этом не воссоздается, поэтому выполнять migrate для этого обновления не придется.

Чтобы убедиться в том, что развертывание стало более безопасным, введите URL проекта с расширением, которое не было определено. Например, попробуйте открыть страницу http://learning-log.herokuapp.com/letmein/. Должна появиться обобщенная страница, которая не сообщает никакой конкретной информации о проекте. Если же вы попробуете применить тот же запрос с локальной версией Learning Log по адресу http://localhost:8000/letmein/, должна появиться стандартная страница ошибки Django. Получается именно то, что нужно: вы будете получать содержательные сообщения об ошибках в процессе разработки проекта, но оградите пользователей от критической информации о коде проекта.

 

Создание специализированных страниц ошибок

В главе 19 мы настроили приложение Learning Log так, чтобы при запросе темы или записи, которая ему не принадлежит, пользователь получал ошибку 404. Вероятно, вы также сталкивались с примерами ошибок 500 (внутренние ­ошибки). Ошибка 404 обычно означает, что код Django правилен, но запрашиваемый объект не существует; ошибка 500 обычно означает, что в написанном вами коде суще­ствует ошибка (например, ошибка в функции из views.py). В настоящее время Django возвращает одну обобщенную страницу ошибки в обеих ситуациях, но мы можем написать собственные шаблоны страниц ошибок 404 и 500, которые соответствуют общему оформлению Learning Log. Эти шаблоны должны находиться в корневом каталоге шаблонов.

 

Создание пользовательских шаблонов

В папке learning_log/learning_log создайте новую папку с именем templates. Затем создайте новый файл с именем 404.html:

404.html

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

{% block header %}

. .

The item you requested is not available. (404)

{% endblock header %}

Этот простой шаблон предоставляет ту же информацию, что и обобщенная страница ошибки 404, но его оформление соответствует остальным страницам сайта.

Создайте другой файл с именем 500.html:

500.html

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

{% block header %}

. .

There has been an internal error. (500)

{% endblock header %}

Новые файлы потребуют небольших изменений в settings.py.

settings.py

...

TEMPLATES = [

{

'BACKEND': 'django.template.backends.django.DjangoTemplates',

. . . .'DIRS': [os.path.join(BASE_DIR, 'learning_log/templates')],

'APP_DIRS': True,

...

},

]

...

Это изменение приказывает Django искать шаблоны страниц ошибок в корневом каталоге шаблонов.

 

Локальный просмотр страниц ошибок

Если вы хотите посмотреть, как будут выглядеть страницы ошибок, в своей системе перед отправкой на сервер Heroku, вам сначала придется установить в локальных настройках режим Debug=False, чтобы подавить выдачу отладочных страниц Django по умолчанию. Для этого внесите следующие изменения в settings.py (убедитесь в том, что вы работаете в части settings.py, относящейся к локальной среде, — а не той, которая относится к Heroku):

settings.py

...

# SECURITY WARNING: don't run with debug turned on in production!

DEBUG = False

ALLOWED_HOSTS = ['localhost']

...

Если DEBUG присвоено значение False, в ALLOWED_HOSTS должен быть указан хотя бы один хост. Теперь запросите тему или запись, которая вам не принадлежит, чтобы увидеть страницу ошибки 404. Затем запросите несуществующий URL-адрес (например, localhost:8000/letmein/), чтобы увидеть страницу ошибки 500.

Завершив проверку, верните DEBUG значение True, чтобы продолжить разработку Learning Log. (Проследите за тем, чтобы настройка DEBUG содержала False в разделе settings.py, относящемся к развертыванию в среде Heroku.)

Примечание

Страница ошибки 500 не содержит никакой информации о текущем пользователе, потому что Django не включает контекстную информацию в ответ при возникновении ошибки сервера.

 

Отправка изменений на Heroku

Теперь необходимо закрепить изменения в шаблоне и отправить их на Heroku:

(1) (ll_env)learning_log$ git add .

(2)(ll_env)learning_log$ git commit -am "Added custom 404 and 500 error pages."

3 files changed, 15 insertions(+), 10 deletions(-)

create mode 100644 learning_log/templates/404.html

create mode 100644 learning_log/templates/500.html

(3)(ll_env)learning_log$ git push heroku master

...

remote: Verifying deploy.... done.

To https://git.heroku.com/learning-log.git

2b34ca1..a64d8d3 master -> master

(ll_env)learning_log$

В точке (1) выдается команда git add ., потому что в проекте были созданы новые файлы, и теперь нужно приказать Git начать отслеживание этих файлов. Затем мы закрепляем изменения (2) и отправляем обновленный проект на Heroku (3). Теперь страницы ошибок имеют такое же оформление, как остальные страницы сайта, а приложение выглядит более профессионально при возникновении ошибок.

 

Использование метода get_object_or_404()

На данный момент, если пользователь вручную запрашивает несуществующую тему или запись, он получает ошибку сервера 500. Django пытается отобразить страницу, но не располагает достаточной информацией для этого, что приводит к ошибке 500. Такая ситуация более точно обрабатывается как ошибка 404, и это поведение можно реализовать при помощи вспомогательной функции Django get_object_or_404(). Эта функция пытается получить запрошенный объект из базы данных, а если этот объект не существует — инициирует исключение 404. Мы импортируем эту функцию в views.py и используем ее вместо get():

views.py

...

from django.shortcuts import render, get_object_or_404

from django.http import HttpResponseRedirect, Http404

...

@login_required

def topic(request, topic_id):

"""Выводит одну тему и все ее записи."""

. .topic = get_object_or_404(Topic, id=topic_id)

# Проверка того, что тема принадлежит текущему пользователю.

...

Теперь при запросе несуществующей темы (например, http://localhost:8000/topics/999999/) появляется страница ошибки 404. Чтобы развернуть это изменение, выполните закрепление и отправьте проект на Heroku.

 

Текущая разработка

Возможно, вы захотите продолжить разработку Learning Log после исходной отправки данных на сервер или создать и развернуть собственные проекты. Существует достаточно четко определенный процесс обновления проектов.

Сначала все необходимые изменения вносятся в локальный проект. Если изменения приводят к появлению новых файлов, добавьте эти файлы в репозиторий Git командой git add . (не забудьте точку в конце команды). Эта команда необходима для любого изменения, требующего миграции базы данных, потому что для каждой миграции генерируется новый файл миграции.

Затем закрепите изменения в репозитории командой git commit -am "сообщение". Отправьте изменения на Heroku командой git push heroku master. Если вы провели локальную миграцию базы данных, также необходимо провести миграцию и для базы данных развернутого приложения. Либо используйте одноразовую команду heroku run python manage.py migrate, либо откройте удаленный терминальный сеанс командой heroku run bash и выполните команду python manage.py migrate. Затем посетите свой проект и убедитесь в том, что предполагаемые изменения вступили в силу.

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

 

Параметр SECRET_KEY

Django использует значение настройки SECRET_KEY из файла settings.py для реализации некоторых протоколов безопасности. В нашем проекте файл настроек был закреплен с включением настройки SECRET_KEY. Для учебного проекта этого достаточно, но на реальном сайте с настройкой SECRET_KEY следует действовать более осторожно. Если вы строите проект, предназначенный для реальной эксплуатации, обязательно изучите вопрос, как повысить безопасность настройки SECRET_KEY.

 

Удаление проекта с Heroku

Очень полезно многократно отработать процесс развертывания на одном проекте или серии малых проектов, чтобы получить представление о развертывании. Однако вы должны знать, как удалить проект после развертывания. Heroku также может ограничивать количество бесплатно развернутых проектов, и загромождать учетную запись учебными проектами нежелательно. Войдите на веб-сайт Heroku (https://heroku.com/), и вы будете перенаправлены на страницу со списком проектов. Щелкните на проекте, который нужно удалить; открывается новая страница с информацией о проекте. Щелкните на ссылке Settings, прокрутите список и найдите ссылку для удаления проекта. Отменить удаление не удастся, поэтому Heroku предложит подтвердить удаление, для чего вам нужно будет вручную ввести имя проекта. Если вы предпочитаете работать в терминальном режиме, проект также можно удалить командой destroy:

(ll_env)learning_log$ heroku apps:destroy --app имя_приложения

Здесь имя_приложения — имя вашего проекта (например, afternoon-meadow-2775 или learning-log, если проект был переименован). Вам также будет предложено снова ввести имя проекта, чтобы подтвердить удаление.

Примечание

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

Упражнения

20-3. Блог в Интернете: разверните проект Blog, над которым вы работали ранее, на сервере Heroku. Проследите за тем, чтобы настройка DEBUG имела значение False, и измените настройку ALLOWED_HOSTS, чтобы развернутая копия была абсолютно безопасной.

20-4. Больше 404: функцию get_object_or_404() также следует применять в представлениях new_entry() и edit_entry(). Внесите изменения, протестируйте их на URL-адресе вида http://localhost:8000/new_entry/99999/ и убедитесь в том, что при этом выводится ошибка 404.

20-5. Расширенное приложение Learning Log: добавьте простую функцию в Learning Log (например, вывод расширенной информации о проекте на домашней странице) и отправьте изменение в развернутую копию. Затем попробуйте внести более сложное изменение — например, чтобы пользователь мог назначить тему общедоступной. Для этого в модель Topic добавляется атрибут с именем public (по умолчанию он должен быть равен False), а на страницу new_topic — элемент формы, позволяющий превратить личную тему в общедоступную. После этого проведите миграцию проекта и переработайте файл views.py, чтобы любая общедоступная тема также была видимой и для пользователей, не прошедших ­аутентификацию. Не забудьте провести миграцию базы данных после отправки изменений на Heroku.

 

Итоги

В этой главе вы узнали, как придать вашему проекту простой, но профессиональный внешний вид при помощи библиотеки Bootstrap и приложения django-bootstrap3. При использовании Bootstrap выбранные вами стили будут работать одинаково практически на всех устройствах, используемых для работы с вашим проектом.

Вы узнали о шаблонах Bootstrap и использовали шаблон Static top navbar для создания простого оформления Learning Log. Вы научились использовать элемент jumbotron для визуального выделения сообщений домашней страницы и узнали, как организовать единое стилевое оформление всех страниц на сайте.

В последней части проекта вы узнали, как развернуть проект на серверах Heroku, чтобы с ним мог работать любой желающий. Вы создали учетную запись Heroku и установили инструменты, упрощающие процесс развертывания. Вы использовали Git для закрепления рабочего проекта в репозитории и отправили репозиторий на серверы Heroku. Наконец, вы узнали, как защитить приложение, включив режим DEBUG=False на работающем сервере.

Итак, работа над Learning Log закончена, и вы можете взяться за построение собственных проектов. Начните с простых приложений и убедитесь в том, что приложение заработало, прежде чем наращивать сложность. Пусть ваше обучение будет интересным — и удачи с вашими собственными проектами!