20.05.2020 • 46 мин. на прочтение

Сайт на питоне за 2 дня

Часть нулевая. Устанавливаем Python

Цель: Подготовить компьютер к работе с Python

Задачи:

  • Описать установку языка на Linux

  • Описать установку языка на Windows

  • Описать установку языка на macOS

Установка в GNU/Linux и BSD

Если вы используете один из дистрибутивов GNU/Linux, таких как Ubuntu, Fedora, OpenSUSE, Debian, CentOS или [ваш вариант], или один из вариантов BSD, как например, FreeBSD, то скорее всего, в вашей системе уже установлен Python.

Чтобы проверить, установлен ли Python на вашей машине с BSD или GNU/Linux, откройте эмулятор терминала (например, konsole или gnome-terminal) и введите команду python -V, как показано ниже.

$ python -V

Python 3.3.0

Примечание: $ – это приглашение командной строки. Оно может выглядеть по-разному в зависимости от настроек вашей ОС, поэтому я буду обозначать приглашение просто одним символом $.

Если вы видите информацию о версии, как показано выше, значит Python у вас уже установлен.

Если же вы получаете такое сообщение:

$ python -V

bash: Python: command not found

значит, Python у вас не установлен. Это маловероятно, но всё же возможно.

В этом случае у вас будут два варианта установки Python:

  • Скомпилировать Python из исходных текстов и установить его. Инструкция по компиляции есть на указанном веб-сайте.

  • Установить бинарные пакеты, используя пакетный менеджер, входящий в комплект поставки вашей ОС, как например, apt-get в Ubuntu/Debian и других дистрибутивах, основанных на Debian, yum в Fedora, pkg_add во FreeBSD, и т.д. Обратите внимание, что для этого потребуется соединение с Интернетом. В противном случае вы можете любым другим способом скопировать бинарники на свой компьютер и установить оттуда.

Установка в Windows

Посетите страницу “http://www.python.org/download/” и загрузите последнюю версию. Установка производится так же, как и для любых других программ для Windows.

Осторожно: Когда вам будет предложено отключить некоторые «опциональные» компоненты, не отключайте ни одного! Некоторые из этих компонентов могут вам пригодиться, особенно IDLE.

Интересно, что большую часть загрузок производят именно пользователи Windows. Конечно, это не даёт представления о полной картине, поскольку у большинства пользователей GNU/Linux Python установлен в системе по умолчанию.

Командная строка DOS

Для использования Python из командной строки Windows, т.е. приглашения DOS, необходимо установить должным образом переменную PATH.

Для Windows 2000, XP, 2003 , перейдите в «Панель управления» → «Система» → «Дополнительно» → «Переменные среды». Нажмите на переменной с именем PATH в отделе «Системные переменные», после этого выберите «Редактировать» и допишите ;C:\Python33 к концу того, что там уже есть (проверьте, существует ли такой каталог, так как для более новых версий Python он будет иметь другое имя). Конечно, укажите действительное имя каталога.

Для более старых версий Windows добавьте следующую строку в файл C:\AUTOEXEC.BAT: „PATH=%PATH%;C:\\Python33“ (без кавычек) и перезапустите систему. Для Windows NT используйте файл AUTOEXEC.NT.

Для Windows Vista:
  1. Нажмите кнопку «Пуск» и выберите «Панель управления».

  2. Нажмите «Система», справа вы увидите «Просмотр основных сведений о вашем компьютере». Слева – список действий, последним из которых будет «Дополнительные параметры системы.» Нажмите её. Отобразится вкладка «Дополнительно» диалога параметров системы. Нажмите кнопку «Переменные среды» справа внизу.

  3. В нижнем поле под названием «Системные переменные» прокрутите до Path и нажмите кнопку «Редактировать».

  4. Измените путь, как нужно.

  5. Перезапустите систему. Vista не обновляет системные пути до перезагрузки.

Для Windows 7-10:
  1. Щёлкните правой кнопкой мыши на значке «Компьютер» на рабочем столе и выберите «Свойства»; иначе – нажмите кнопку «Пуск» и выберите «Панель Управления»→«Система и безопасность»→«Система». Нажмите «Дополнительные параметры системы» слева, а затем выберите вкладку «Дополнительно». Внизу нажмите кнопку «Переменные среды» и в отделе «Системные переменные» найдите пере менную PATH, выберите её и нажмите «Редактировать».

  2. Перейдите к концу строки в поле «Значение переменной» и допишите ;C:\Python33.

  3. Если значение переменной было %SystemRoot%\system32;, теперь оно примет вид %SystemRoot%\system32;C:\Python33

  4. Нажмите «Ok», и всё. Перезагрузка не требуется.

Если вы должным образом установили значение переменной PATH, теперь можно запускать интерпретатор из командной строки.

Чтобы открыть терминал в Windows, нажмите кнопку «Пуск» и выберите «Выполнить». В появившемся диалоговом окне наберите cmd и нажмите Enter.

Затем наберите python и проверьте, нет ли ошибок.

Для пользователей Mac OS X

У пользователей Mac OS X Python уже будет установлен в системе. В противном случае вы можете открыть терминал, нажав Command+Пробел, набрав в открывшейся строке поиска Terminal и нажав Enter.

Затем установить Homebrew, выполнив:

ruby -e "\$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"

После чего установить Python 3 при помощи:

brew install python3

А теперь запустите python3 -V и проверьте, нет ли ошибок.

Часть первая. Выбор IDE, фреймворка и настройка пустого проекта

Цель: Подготовить Python к работе над создание сайта

Задачи:

  • Установить библиотеку Django
  • Создать проект сайта
  • Настроить сервер проекта

Установка PyCharm и всех библиотек

Для выполнения работы рекомендуется использование IDE PyCharm, так как в нём удобно организовано рабочее место со строкой терминала и дебаг-платформой.

Выбор фреймворка пал на библиотеку Django. На Django реализовано большое количество крупнейших платформ: YouTube, Google Search, DropBox, Instagram, Reddit, Pinterest, Yhoo! Maps, Spotify и многие другие проекты.

Для начала, нам необходимо скачать фреймворк. Заходим в терминал и пишем 2 команды:

pip install pip

pip install Django

Запускаем PyCharm и создаём новый Django проект

Когда мы выбираем новый Django проект, PyCharm автоматически пишет следующую команду:

django-admin startproject C:/Users/Valery/PycharmProjects/MySite

Чтобы ознакомиться со всеми возможными командами, напишите в терминале:

django-admin

Откроем созданный нами проект и заглянем в папку

В папке (я создавал MySite) мы видим ещё одну папку с тем же названием и файл manage.py. Это основной наш фал. Благодаря ему, мы можем запускать проект в терминале, выполнять отладку/изменения, запускать сервер и т.д.

Перейдём в папку MySite и в ней мы обнаружим несколько файлов: __init__.py – он указывает, что это пакет питона и сейчас он пуст, asgi.py – файл, в который можно загружать дополнения, settings.py – файл для глобальных настроек с документацией, urls.py – файл для обработки адресов страниц, wsgi.py – файл, указывающий способ взаимодействия с сервером.

Изучение окружения

Откроем терминал

В нём введём команду:

python manage.py runserver

Открываем любой браузер и вводим в адресную строку

http://127.0.0.1:8000

Мы запустили локальный сервер на ПК и получили доступ к сайту.

Перейдём в панель администратора введя в конце строки /admin

Панель администратора тоже работает.

В терминале же мы видим всё, что происходило на сервере

Для выключения сервера нажмите

CTRL+C

Часть вторая. Написание страницы и отслеживание URL

Цель: Создать первые страницы и отследить их URL

Задачи:

  • Создать приложение в проекте

  • Создать страницы в приложении проекта

  • Отладка сервера проекта

Небольшой экскурс в историю

Весь интернет работает по одному основному протоколу и ряду дополнительных. Основной протокол – HTTP (от англ. HyperText Transfer Protocol — протокол передачи гипертекста). HTTP – это прикладной протокол передачи данных в сети. На текущий момент используется для получения информации с веб-сайтов. Протокол HTTP основан на использовании технологии «клиент-сервер»: клиент, отправляющий запрос, является инициатором соединения; сервер, получающий запрос, выполняет его и отправляет клиенту результат.

HTTP был предложен в марте 1991 года Тимом Бернерсом-Ли, работавшим тогда в CERN, как механизм для доступа к документам в Интернете и облегчения навигации посредством использования гипертекста. Самая ранняя версия протокола HTTP/0.9 была впервые опубликована в январе 1992 года (хотя реализация датируется 1990 годом).

Шли годы и опасность в интернете росла. С возрастание угроз стало необходимо шифрование. Так появился HTTPS (от англ. HyperText Transfer Protocol Secure — безопасный протокол передачи гипертекста) — это расширение протокола HTTP, поддерживающее шифрование посредством криптографических протоколов SSL и TLS, где SSL и TLS дополнили основной HTTP.

Для работы с HTTP протоколом существует свой язык – HTML. HTML (от англ. HyperText Markup Language — «язык гипертекстовой разметки») — стандартизированный язык разметки документов во Всемирной паутине. Большинство веб-страниц содержат описание разметки на языке HTML (или XHTML). Язык HTML интерпретируется браузерами; полученный в результате интерпретации форматированный текст отображается на экране монитора компьютера или мобильного устройства.

Теперь вернёмся к нашему проекту. По возвращению, мы видим новый файл – db.sqlite3. Этот файл появился после запуска сервера. Он – наша база данных и понятно, пока, пустая.

Создание приложения

Переходим в терминал и пишем команду

python manage.py startapp blog

Мы создали новую директорию под названием blog. blog – это приложение для нашего проекта сайта «MySite».

Пишем страницу

Открываем views.py.

Пишем строку импорта новой библиотеки

from django.http import HttpResponse

Напишем простую функцию

def home(request):
    return HttpResponse('"h2"Привет мир!"/h2"')

Не забываем про pep8 (руководство по написанию кода на Python). Ссылка на полное руководство – https://pythonworld.ru/osnovy/pep-8-rukovodstvo-po-napisaniyu-koda-na-python.html

Теперь нам нужно её вызвать. Приступим.

В приложении blog создадим файл – urls.py. Для этого откроем папку с проектом. В моём случае это C:\Users\Valery\PycharmProjects\MySite\blog. Затем, создаём файл.

Обратимся к автоматически созданному файлу urls.py в папке C:\Users\Valery\PycharmProjects\MySite. Откроем его.

Построчно разберём код

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

from django.contrib import admin – импорт библиотеки для создание панели администратора сайта.

from django.urls import path – импорт библиотеки для создание списка адресов страниц.

urlpatterns = [
    path('admin/', admin.site.urls),
]

Организация списка url-файлов

Скопируем кусок в C:\Users\Valery\PycharmProjects\MySite\blog\urls.py. Копируем всё, кроме библиотеки на панель администратора. То есть:

from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

Заменим path('admin/', admin.site.urls), на path('', views.home),. Результат:

from django.urls import path

urlpatterns = [
    path('', views.home),
]

Что мы сделали? Мы вызываем главную страницу нашего проекта, то есть (“http://127.0.0.1:8000/blog/”), а вызов идёт в файл views.py в приложении blog и обращается к функции home, которую мы создали.

Есть только 1 маленькая проблема – фатальная ошибка компиляции. Файл urls.py не «видит» файла views.py. Исправляем:

from . import views

from . означает, что импорт идёт из корневой для приложения директории, то есть C:\Users\Valery\PycharmProjects\MySite\blog\.

Хлебные крошки

Добавим последний штрих – хлебную крошку. Верстальщики называют хлебными крошками – имена ключевых объектов/директорий/файлов и т.п. Хлебные крошки – это навигационная цепочка на сайте. Свой название оно получило по аналогии с немецкой сказкой «Гензель и Гретель», в которой дети, когда их повторно завели в лес, не смогли найти дорогу обратно, так как вместо камешков оставили хлебные крошки, которые впоследствии склевали лесные птицы.

Теперь к делу. Итоговая вёрстка файла urls.py выглядит так:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='blog-home'),
]

Теперь мы не заблудимся и вернёмся в главную директорию.

Если бы мы сейчас искали приложение blog, мы бы его не нашли. Дело в том, что в urls.py в директории C:\Users\Valery\PycharmProjects\MySite\ указана ссылка только на приложение admin. Исправим это.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
]

Мы подключаем ссылку blog и все её url-файлы командой include. Чтобы она работала, мы импортируем её во второй строке.

Запускаем сервер и проверяем.

Вуаля. Всё сломалось. Так и должно быть, так как на главной странице у нас ничего нет. Перейдём в blog.

Проверим admin

Победа.

Закрепление

Напишем ещё одну страницу для закрепления. Работаем в директории blog. Переходим в файл viewes.py и в нём пишем ещё одну функцию.

def contacts(request):
return HttpResponse('"h2"Контакты"/h2"')

Переходим в urls.py. Пишем новую ссылку:

urlpatterns = [
    path('', views.home, name='blog-home'),
    path('contacts/', views.contacts, name='blog-contacts'),
]

Теперь у нас будет новый путь: “http://127.0.0.1:8000/blog/contacts

Переходим на папку вверх в MySite. Заходим в файл urls.py и ничего там не меняем

Почему? Командой include(‘blog.urls’) мы проверяем все ссылки второго уровня.

Запуск сервера. Проверка.

Всё работает.

Часть третья. HTML, CSS, JavaScript

Цель: Изучение основополагающих строения сайта

Задачи:

  • Изучить устройство сайта

  • Изучение основ HTML

  • Изучение основ CSS

  • Изучение основ JS

  • Рекомендация литературы для углубления знаний

О всех сайтах в мире

Все сайты устроены, примерно так:

Сравним человеческий организм с этим механизмом. В основе у нас кости. Как бы мы ни накачивали мышцы, ни тренировались мы не сможем повернуть голову за спину или же ходить коленками назад. Основа – кости. То, как устроен наш скелет – диктует нам как мы сможем жить.

Далее идут мышцы. Костей человека мы не видим, но догадываемся, что они есть, а вот мышцы мы видим, но не напрямую (красных сжимающихся/разжимающихся штук на теле человека не так уж обыденно). От силы и натренированности мышц зависит качество работы скелета. Человек может прыгать, бегать, шевелиться, а скелет – нет.

Кожа. Это штука не только закрывает мышцы и делает нас красивыми (кого-то просто красивее, чем раньше), но и защищает мышцы от этого сердитого мира.

Косметика. Это не только украшение и скрытие неровностей и изъянов кожи, но и дополнительный слой, питающий кожу.

Теперь о главном. Кости – это движок сайта. Он бывает написан или на PHP, или на Python. Есть ещё море CMS – автоматических движков, но это для тех, кто не может выучить язык программирования, то есть не про нас.

HTML – мышцы. Он выглядит ну очень страшно, но работает как атомные часы. Без него – сайт невозможен.

CSS – это кожа, которая скрывает ужас HTML под красивым словом «стиль». Стили не всегда красивы, но задача у них одна – «приодеть» сайт.

JavaScript – это косметика. Если вы видите, что на сайте что-то дёргается (красиво дёргается, а не в конвульсиях), перемещается и как-то иначе реагирует на курсор, клавиатуру – это JS.

Движок у нас – Python. PHP сложнее и старше. Он медленно идёт на покой. Медленно, но идёт.

Азы HTML

Быстрый старт

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

В примере 1 приведен несложный пример такого кода.

Пример 1. Первая веб-страница

"!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd""
"html"
"head"
    "meta http-equiv="Content-Type" content="text/html; charset=utf-8""
    "title"Моя первая веб-страница"/title"
"/head"
"body"
    "h1"Заголовок страницы"/h1"
    "p"Основной текст"/p"

"/body"
"/html"

Чтобы посмотреть результат примера в действии, проделайте следующие шаги.

  1. В Windows откройте программу Блокнот (Пуск ” Выполнить ” набрать «notepad» или Пуск ” Программы ” Стандартные ” Блокнот).

  2. Наберите или скопируйте код в Блокноте (рис. 1).

Рис. 1. Вид HTML-кода в программе Блокнот

  1. Сохраните готовый документ (Файл ” Сохранить как…) под именем c:\www\example11.html, при этом обязательно поставьте в диалоговом окне сохранения тип файла: Все файлы и кодировку UTF-8 (рис. 2). Обратите внимание, что расширение у файла должно быть именно html.

Рис. 2. Параметры сохранения файла в Блокноте

  1. Запустите браузер Internet Explorer (Пуск ” Выполнить ” набрать «iexplore» или Пуск ” Программы ” Internet Explorer).

  2. В браузере выберите пункт меню Файл ” Открыть и укажите путь к вашему файлу.

  3. Если все сделано правильно, то в браузере вы увидите результат, как показано на рис. 3.

Рис. 3. Вид веб-страницы в окне браузера

В случае возникновения каких-либо ошибок проверьте правильность набора кода согласно примеру 1, расширение файла (должно быть html) и путь к документу.

Учить HTML нет никакого смысла. Вы научитесь понимать этот язык только практикой. Просто пользуйтесь параллельно.

Самоучитель HTML – “http://htmlbook.ru/samhtml

Справочник HTML – “http://htmlbook.ru/html

Азы CSS

После знакомства с HTML разработчики сайтов разделяются на две основные категории. Одна часть считает, что с помощью HTML на сайте можно создавать всё или практически всё, другая же понимает, что в целом средств разметки недостаточно для оформления веб-документов. Действительно, HTML лишь первый этап в процессе обучения созданию сайтов. Следующим шагом является изучение стилей или CSS (Cascading Style Sheets, каскадные таблицы стилей).

Стили представляют собой набор параметров, управляющих видом и положением элементов веб-страницы. Чтобы стало понятно, о чем идет речь, посмотрим на рис. 4.

Рис. 4. Веб-страница, созданная только на HTML

Это обычная веб-страница, оформленная без всяких изысков. Тот же самый документ, но уже с добавлением стилей приобретает совершенно иной вид (рис. 5).

Рис. 5. Веб-страница, созданная на HTML и CSS

Перемена разительна, поэтому заглянем в код, чтобы понять, в чем же разница (пример 2).

Пример 2. Исходный код документа

"!DOCTYPE HTML"
"html"
    "head"
        "title"Флексагон"/title"
        "meta charset="utf-8""
        "link rel="stylesheet" href="style.css""
    "/head"
"body"
    "h1"Флексагон"/h1"
    "p"Флексагон представляет собой бумажную фигуру, которая имеет три и более стороны. Поначалу кажется, что это невозможно, но вспомните ленту Мёбиуса, она ведь имеет всего одну сторону, в отличие от листа бумаги, и, тем не менее, реальна. Так же реален и флексагон, который легко сделать и склеить в домашних условиях. Он выглядит как двухсторонний шестиугольник, но стоит согнуть его особым образом, и мы увидим третью сторону. Легко убедиться, что мы имеем дело именно с тремя сторонами, если раскрасить их в разные цвета. Перегибая флексагон, по очереди будем наблюдать все его поверхности."/p"
    "/body"
"/html"

Сам код HTML никаких изменений не претерпел и единственное добавление — это строка "link rel="stylesheet" href="style.css"". Она ссылается на внешний файл с описанием стилей под именем style.css. Содержимое этого файла показано в примере 3.

Пример 3. Содержимое стилевого файла style.css

body {
    font-family: Arial, Verdana, sans-serif; /* Семейство шрифтов */
    font-size: 11pt; /* Размер основного шрифта в пунктах */
    background-color: #f0f0f0; /* Цвет фона веб-страницы */
    color: #333; /* Цвет основного текста */
}
h1 {
    color: #a52a2a; /* Цвет заголовка */
    font-size: 24pt; /* Размер шрифта в пунктах */
    font-family: Georgia, Times, serif; /* Семейство шрифтов */
    font-weight: normal; /* Нормальное начертание текста */
}
p {
    text-align: justify; /* Выравнивание по ширине */
    margin-left: 60px; /* Отступ слева в пикселах */
    margin-right: 10px; /* Отступ справа в пикселах */
    border-left: 1px solid #999; /* Параметры линии слева */
    border-bottom: 1px solid #999; /* Параметры линии снизу */
    padding-left: 10px; /* Отступ от линии слева до текста */
    padding-bottom: 10px; /* Отступ от линии снизу до текста */
}

В файле style.css как раз и описаны все параметры оформления таких тегов как "body""h1" и "p". Заметьте, что сами теги в коде HTML пишутся как обычно.

Поскольку на файл со стилем можно ссылаться из любого веб-документа, это приводит в итоге к сокращению объёма повторяющихся данных. А благодаря разделению кода и оформления повышается гибкость правления видом документа и скорость работы над сайтом.

CSS представляет собой свой собственный язык, который совпадает с HTML только некоторыми значениями, например способом определения цвета.

Типы стилей

Различают несколько типов стилей, которые могут совместно применяться к одному документу. Это стиль браузера, стиль автора и стиль пользователя.

Стиль браузера

Оформление, которое по умолчанию применяется к элементам веб-страницы браузером. Это оформление можно увидеть в случае «голого» HTML, когда к документу не добавляется никаких стилей. Например, заголовок страницы, формируемый тегом "H1", в большинстве браузеров выводится шрифтом с засечками размером 24 пункта.

Стиль автора

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

Стиль пользователя

Это стиль, который может включить пользователь сайта через настройки браузера. Такой стиль имеет более высокий приоритет и переопределяет исходное оформление документа. В браузере Internet Explorer подключение стиля пользователя делается через меню Сервис ” Свойство обозревателя ” Кнопка «Оформление», как показано на рис. 6.

Рис. 6. Подключение стиля пользователя в браузере Internet Explorer

В браузере Opera аналогичное действие происходит через команду Инструменты ” Общие настройки ” Вкладка «Расширенные» ” Содержимое ” Кнопка «Параметры стиля» (рис. 7).

Рис. 7. Подключение стиля пользователя в браузере Opera

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

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

Самоучитель CSS – “http://htmlbook.ru/samcss

Справочник CSS – “http://htmlbook.ru/css

Немного о JavaScript

JS – серьёзный язык программирования. Выучить его за 2 секунды не получится, но написать простейшую анимацию – легче лёгкого. Яркий пример помощи разработчиков – “https://www.w3schools.com/howto/default.asp

И наконец, потрясающая книга от не менее потрясающего автора – Стива Круга, «Не заставляйте меня думать». Книгу переиздают уже 20 лет. Я учился по второй версии, а сейчас посоветую третью. Это лучший самоучитель для понимания того, как должен выглядеть сайт.

Часть четвёртая. Шаблон сайта

Цель: Создание полноценного сайта с использованием шаблонизатора

Задачи:

  • Создание простых страниц на HTML
  • Изменение ссылок внутри проекта
  • Введение динамических и статических элементов страницы
  • Установка Bootstrap
  • Применение шаблонов Bootstrap
  • Графическая настройка страницы
  • Создание статических стилей

Создаём html-страницы

В этой части курса мы научимся выводить полноценные html-страницы. Так как, мы хотим создать шаблон страниц, а не просто одну страницу, мы должны прибегнуть к полноценной вёрстке на Python. Для этого, в папке нашего приложения blog, нужно создать папку templates. Название папки зарезервировано плагином Django, так как Django каждый раз собирает наши файлы и с нуля отрисовывает страницу. При сборке сайта, джанго обращается к папкам и файлам с конкретными названиями.

Теперь, в папке templates, нам нужно создать ещё одну папку, которая точно также называется, как и приложение, то есть в нашем случае – blog.

Почему именно так? Дело в том, что Django собирает все папки в единую папку templates. Сейчас у нас одно приложение – blog, но если бы у нас было бы ещё несколько приложений, то в папке templates был бы хаос из файлов. Несмотря на то, что у нас одно приложение, мы будем писать сайт с правилами хорошего тона в программировании.

Теперь в папке blog, создадим файлы home.html и contacts.html

Как мы видим, файлы у нас не пусты.

"!DOCTYPE html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "title"Title"/title"
    "/head"
    "body"

    "/body"
"/html"

Удалим всё лишнее.

Настроим PyCharm. Нам потребуется плагин для работы с html-файлами. Плагин называется – Emmet.

Переходим в IDE по следующей ветке: File -” Settings

В панели поиска напишем название нашего плагина

Обычно, он установлен по умолчанию и находится во вкладке Editor. Если его у вас нет, нажмите кнопку Install в появляющемся после запроса окне.

Как мы видим, плагин будет реагировать на кнопку “Tab”. Это нам и нужно. Нажимаем ОК и возвращаемся к файлам html.

Введите ! и нажмите Tab.

Весь текст набрался самостоятельно.

Не меняем ничего, кроме двух пунктов.

  1. Удалим в поле "title" слово “Documents”

  2. В теле введём заголовок "h2"

Результат (contacts.html):

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title""/title"
    "/head"
    "body"
        "h2"Контакты работают иначе"/h2"
    "/body"
"/html"

Теперь, чтобы шаблоны были доступны, необходимо в главном файле настройки проекта – settings.py в установленных приложениях (INSTALLED_APPS) ввести наше приложение – blog.

Сделаем тоже самое для главной страницы.

Результат (home.html):

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title""/title"
    "/head"
    "body"
        "h2"Ура! Главная страница поменялась"/h2"
    "/body"
"/html"

Переходим к файлу настроек и вписываем туда строку:

blog.apps.BlogConfig

Таким образом, мы вводим приложение blog, сведения о котором хранятся в файле apps и обращаемся к функции BlogConfig.

Результат:

INSTALLED_APPS = [
    'blog.apps.BlogConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Взглянем на файл apps.py в проекте сайта.

from django.apps import AppConfig


class BlogConfig(AppConfig):
    name = 'blog'

Остался последний шаг – настроить vievs.py. Сейчас там прописаны функции – HttpResponse, то есть ответы через http. Это неправильно. Сайт будет работать на html вёрстке и нам нужно не выдавать http ответы, а обращаться к html шаблонам. Исправляем:

from django.shortcuts import render
from django.http import HttpResponse


def home(request):
    return render(request, 'blog/home.html')


def contacts(request):
    return render(request, 'blog/contacts.html')

Обратите внимание на сигналы PyCharm:

Строка с импортом библиотеки HttpResponse стала серой. Это знак того, что мы не использовали в фале программы эту библиотеку. Её можно удалить.

Помимо прочего, появилось зелёные ярлычки слева. Это знак, что мы обращаемся к нашему html-файлу. Если навести на него курсор, отобразиться имя файла, а если кликнуть по нему, мы перейдём в этот файл.

Запускаем сервер и проверяем как всё работает:

Всё работает как надо!

Создаём html-страницы с динамическими данными

Теперь научимся передавать динамические данные. Это – заготовка под базы данных, которыми мы потом будем пользоваться.

Перейдём в файл views.py.

Написав немного кода, я изменил файл так:

from django.shortcuts import render

news = [
    {
        'title': 'Первая запись',
        'text': 'Много-много текста',
        'date': '10 Мая 2020',
        'author': 'Валерий'
    },
    {
        'title': 'Вторая запись',
        'text': 'Снова много-много текста',
        'date': '19 Мая 2020',
        'author': 'Егор'
    }
]


def home(request):
    data = {
        'news': news,
        'title': 'Главная страница'
    }
    return render(request, 'blog/home.html', data)


def contacts(request):
    return render(request, 'blog/contacts.html')

Построчно разберём что к чему. Создан список news, состоящий из 2 записей. Каждая запись – это словарь. В каждом словаре по 4 элемента. В функции отрисовки главной страницы, я добавил переменную data, которая создаёт словарь news и вызывает в него созданный список новостей. Плюс к этому, в data мы вызывает ещё один объект – заголовок страницы (title). В самом же рендере, мы добавили переменную в конце и вызываем её.

Теперь перейдём в html-файл нашей главной страницы (home.html)

Снова написав немного кода, получаем следующее:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
    "/head"
    "body"
        {% for post in news %}
            "h1"{{ post.title }}"/h1"
            "p"{{ post.text }}"/p"
            {% if post.author == 'Валерий' %}
                "p"Автор: Админ"/p"
            {% else %}
                "p"Автор: {{ post.author }}"/p"
            {% endif %}
            "p"Дата: {{ post.date }}"/p"
        {% endfor %}
    "/body"
"/html"

В поле “title” мы вызываем нужную нам строку – «Главная страница». В теле мы используем 2 конструкции:

  1. for

  2. if

Так как, мы пишем вёрстку на Python в html-файле, конструкции используются при помощи такой конфигурации: {% %}

Если бы мы писали тот же код, но на чистом питоне, выглядел бы он так:

for post in news:
    print('post.title')
    print('post.text')
    if post.author == 'Валерий':
        print('Автор: Админ')
    else:
        print('Автор: ', post.author)
    print('Дата: ', post.data)

Посмотрите основные отличия:

  • Отсутствие двоеточий после for и if, но наличие конструкции endfor и endif

  • Добавлена разметка html, то есть “p”, “h2” и т.п.

  • Отсутствие кавычек и слова “print”

Запустим сервер и посмотрим на результат:

Подредактируем ещё немного файл views.py. Допустим, нам нужно вывести только заголовок (title), а остаток кода не менять и не выводить все новости (data). В таком случае, сделаем следующую конструкцию:

def contacts(request):
    return render(request, 'blog/contacts.html', {'title': 'Страничка про МИИГАиК'})

А в файл contacts.html выглядит теперь так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
    "/head"
    "body"
        "h2"Контакты работают иначе"/h2"
    "/body"
"/html"

Проверяем:

Теперь давайте сравним 2 файла home.html и contacts.html. Что в них отличается?

Единственный блок, который у них отличается – тело, а «шапка» (верхняя часть сайта) и «подвал» (нижняя часть сайта) остаются одинаковыми. Конечно, нам не будет интересно переписывать один и тот же код на каждой странице. Давайте исправим это неудобство.

Создадим рядом с файлами home.html и contacts.html файл main.html и пишем в него следующий код:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
    "/head"
    "body"
        {% block main_section %}
        {% endblock %}
    "/body"
"/html"

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

{% block main_section %}
{% endblock %}

Перейдём в файл contacts.html и перепишем его таким образом:

{% extends 'blog/main.html' %}
{% block main_section %}
    "h2"Контакты работают иначе"/h2"
{% endblock main_section %}

То есть, мы обращаемся к файлу blog/main.html и из него берём всё, что было до блока, пишем блок (тело страницы) и забираем всё, что нужно после. Повторяем операцию с файлом home.html.

{% extends 'blog/main.html' %}
{% block main_section %}
    {% for post in news %}
        "h1"{{ post.title }}"/h1"
        "p"{{ post.text }}"/p"
        {% if post.author == 'Валерий' %}
            "p"Автор: Админ"/p"
        {% else %}
            "p"Автор: {{ post.author }}"/p"
        {% endif %}
    "p"Дата: {{ post.date }}"/p"
    {% endfor %}
{% endblock main_section %}

Проверяем и видим тоже самое. Давайте теперь напишем какую-нибудь глобальную фразу в main.html. Например, так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
    "/head"
    "body"
        "h1"МИИГАиК - лучший ВУЗ!"/h1"
        {% block main_section %}
        {% endblock %}
    "/body"
"/html"

Проверим что получилось:

Теперь эта фраза нас преследует везде и на каждой странице. Сейчас это изменение можно убрать, так как нам ещё предстоит много работы со станицами.

Bootstrap

Перейдём к последнему блоку – фреймворку Bootstrap.

Bootstrap – это фреймворк, в котором прописаны ряд CSS стилей и JavaScript скриптов. Их можно использовать, прописывая их у нас в проекте.

Переходим на сайт “https://www.bootstrapcdn.com

Копируем первую строку кода:

$“https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css

Переходим в main.html и до закрытия «головы» сайта (head) прописывает link, нажимаем Tab и вставляем скопированную ссылку. Должно получиться вот так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        {% block main_section %}
        {% endblock %}
    "/body"
"/html"

Сейчас мы подключили CSS стиль к нашему сайту. Посмотрим на результат:

Не сказать, что сайт стал красивым, но он уже начал своё преображение. Продолжим.

Пишем в теле main.html «main.container» и жмём Tab (спасибо, Emmet). Должно получиться так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        "main class="container""
            {% block main_section %}
            {% endblock %}
        "/main"
    "/body"
"/html"

Результат:

Теперь, добавим шапку. Для этого переходим на сайт “https://getbootstrap.com”. На нём, переходим во вкладку Examples, затем – Navbars.

Выбираем понравившуюся панель. Кликаем по ней правой кнопкой мыши -” Показать код элемента

В коде выделяем элемент целиков, как показано на скриншоте и нажимаем кнопку Copy Element

Скопированный элемент вставляем в тело в файле main.html. Вот так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        "nav class="navbar navbar-expand-lg navbar-light bg-light rounded""
            "a class="navbar-brand" href="#""Navbar"/a"
            "button class="navbar-toggler" type="button" data-toggle="collapse" data-arget="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation""
                "span class="navbar-toggler-icon"""/span"
            "/button"

            "div class="collapse navbar-collapse" id="navbarsExample09""
                "ul class="navbar-nav mr-auto""
                    "li class="nav-item active""
                        "a class="nav-link" href="#""Home "span class="sr-only""(current)"/span""/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link" href="#""Link"/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true""Disabled"/a"
                    "/li"
                    "li class="nav-item dropdown""
                        "a class="nav-link dropdown-toggle" href="#" id="dropdown09" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false""Dropdown"/a"
                        "div class="dropdown-menu" aria-labelledby="dropdown09""
                            "a class="dropdown-item" href="#""Action"/a"
                            "a class="dropdown-item" href="#""Another action"/a"
                            "a class="dropdown-item" href="#""Something else here"/a"
                        "/div"
                    "/li"
                "/ul"
                "form class="form-inline my-2 my-md-0""
                    "input class="form-control" type="text" placeholder="Search" aria-label="Search""
                "/form"
            "/div"
        "/nav"
        "main class="container""
            {% block main_section %}
            {% endblock %}
        "/main"
    "/body"
"/html"

Осталось отредактировать шаблон. Так и сделаем:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        "nav class="navbar navbar-expand-lg navbar-light bg-light rounded""
            "a class="navbar-brand" href="/blog/""МИИГАиК"/a"
            "button class="navbar-toggler" type="button" data-toggle="collapse" data-arget="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation""
                "span class="navbar-toggler-icon"""/span"
            "/button"

            "div class="collapse navbar-collapse" id="navbarsExample09""
                "ul class="navbar-nav mr-auto""
                    "li class="nav-item active""
                        "a class="nav-link" href="/blog/""Главная"/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link" href="/blog/contacts""О ВУЗе"/a"
                    "/li"
                "/ul"
            "/div"
        "/nav"
        "main class="container""
            {% block main_section %}
            {% endblock %}
        "/main"
    "/body"
"/html"

Результат:

На этом моменте, становиться видна одна проблема: ссылка на главную страницу выглядит так:

"a class="navbar-brand" href="/blog/""МИИГАиК"/a", то есть главной страницы у нас нет. Мы переходим на страницу второго уровня – blog. Исправим это. Переходим в urls.py в папке проекта (MySite). В файле меняем одно поле.

С этого:

path('/blog', include('blog.urls')),

на это:

path('', include('blog.urls')),

Затем поменяем ссылки в main.html с:

"a class="navbar-brand" href="/blog/""МИИГАиК"/a"

на:

"a class="navbar-brand" href="/""МИИГАиК"/a"

Финальный код выглядит так:

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        "nav class="navbar navbar-expand-lg navbar-light bg-light rounded""
            "a class="navbar-brand" href="/""МИИГАиК"/a"
            "button class="navbar-toggler" type="button" data-toggle="collapse" data-arget="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation""
                "span class="navbar-toggler-icon"""/span"
            "/button"

            "div class="collapse navbar-collapse" id="navbarsExample09""
                "ul class="navbar-nav mr-auto""
                    "li class="nav-item active""
                        "a class="nav-link" href="/""Главная"/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link" href="/contacts""О ВУЗе"/a"
                    "/li"
                "/ul"
            "/div"
        "/nav"
        "main class="container""
            {% block main_section %}
            {% endblock %}
        "/main"
    "/body"
"/html"

Проверяем адрес главной страницы:

Всё в порядке.

Редактируем стиль в Bootstrap

Теперь вы можете самостоятельно отредактировать сайт с пояснениями из Bootstrap – “https://getbootstrap.com/docs”. Помните один важный момент – Bootstrap разделяет страницу по вертикали на 12 колонн равной величины, а по горизонтали – разделений нет.

Я настроил сайт по своему вкусу и вот, что у меня получилось (работаем только с файлом main.html):

"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
    "/head"
    "body"
        "nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-5""
            "a class="navbar-brand" href="/""МИИГАиК"/a"
            "button class="navbar-toggler" type="button" data-toggle="collapse" data-
arget="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation""
                "span class="navbar-toggler-icon"""/span"
            "/button"

            "div class="collapse navbar-collapse" id="navbarsExample09""
                "ul class="navbar-nav mr-auto""
                    "li class="nav-item active""
                        "a class="nav-link" href="/""Главная"/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link" href="/contacts""О ВУЗе"/a"
                    "/li"
                "/ul"
            "/div"
            "div class="navbar-nav""
                "a href="tel:+74993227800" class="btn btn-outline-secondary""Позвонить"/a"
            "/div"
        "/nav"
        "main class="container""
            "div class="row""
                "div class="col-md-8""
                    {% block main_section %}
                    {% endblock %}
                "/div"

                "aside class="col-md-4""
                    "div class="p-3""
                        "h3""b"Интересные новости"/b""/h3"
                        "img src="http://www.miigaik.ru/upload/medialibrary/6c5/6c57c4e2a73db9f0dc225b28c8dab3f6.png" height="400""
                        "p"Международная научно-техническая онлайн конференция «Пространственные данные в условиях цифровой трансформации» станет ключевым мероприятием, приуроченным к дате основания Московского государственного университета геодезии и картографии (МИИГАиК) 25 мая 1779 года и пройдет в период с 25 по 27 мая 2020 года."/p"
                        "a href="http://www.miigaik.ru/about/" target="_blank""
                            "button class="btn btn-warning""Посмотреть"/button"
                        "/a"
                    "/div"
                "/aside"
            "/div"
        "/main"
    "/body"
"/html"

Результат:

Внимательно изучите код и прочитайте о не понятных тегах в самоучителе по html и bootstrap.

Статистические данные

Займёмся статическими файлами.

В папке приложения blog создадим папку static (имя зарезервировано) и в ней создадим папку blog (аналогично templates). В эту папку добавим css-файл – main.css.

В файле напишем следующее:

body {
    background: #fafafa;
}

Таким образом, мы заменили цвет фона с белого на кремовый (можете «поиграть» с цветом).

Чтобы статические файлы заработали на сайте, в файле main.html пропишем в самом начале следующую строку:

{% load static %}

Теперь введём ещё один стиль CSS (вспомните Bootstrap), но путь уже будет не ссылкой, а статический относительный, т.е.:

"link rel="stylesheet" href="{% static 'blog/main.css' %}""

Чтобы стиль применился, перезапустите сервер.

Финальный код main.html:

{% load static %}
"!doctype html"
"html lang="en""
    "head"
        "meta charset="UTF-8""
        "meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0""
        "meta http-equiv="X-UA-Compatible" content="ie=edge""
        "title"{{ title }}"/title"
        "link rel="stylesheet" ref="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css""
        "link rel="stylesheet" href="{% static 'blog/main.css' %}""
    "/head"
    "body"
        "nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-5""
            "a class="navbar-brand" href="/""МИИГАиК"/a"
            "button class="navbar-toggler" type="button" data-toggle="collapse" data-
arget="#navbarsExample09" aria-controls="navbarsExample09" aria-expanded="false" aria-label="Toggle navigation""
                "span class="navbar-toggler-icon"""/span"
            "/button"

            "div class="collapse navbar-collapse" id="navbarsExample09""
                "ul class="navbar-nav mr-auto""
                    "li class="nav-item active""
                        "a class="nav-link" href="/""Главная"/a"
                    "/li"
                    "li class="nav-item""
                        "a class="nav-link" href="/contacts""О ВУЗе"/a"
                    "/li"
                "/ul"
            "/div"
            "div class="navbar-nav""
                "a href="tel:+74993227800" class="btn btn-outline-secondary""Позвонить"/a"
            "/div"
        "/nav"
        "main class="container""
            "div class="row""
                "div class="col-md-8""
                    {% block main_section %}
                    {% endblock %}
                "/div"

                "aside class="col-md-4""
                    "div class="p-3""
                        "h3""b"Интересные новости"/b""/h3"
                        "img src="http://www.miigaik.ru/upload/medialibrary/6c5/6c57c4e2a73db9f0dc225b28c8dab3f6.png" height="400""
                        "p"Международная научно-техническая онлайн конференция «Пространственные данные в условиях цифровой трансформации» станет ключевым мероприятием, приуроченным к дате основания Московского государственного университета геодезии и картографии (МИИГАиК) 25 мая 1779 года и пройдет в период с 25 по 27 мая 2020 года."/p"
                        "a href="http://www.miigaik.ru/about/" target="_blank""
                            "button class="btn btn-warning""Посмотреть"/button"
                        "/a"
                    "/div"
                "/aside"
            "/div"
        "/main"
    "/body"
"/html"

Последним штрихом, я изменил вывод статей на такой:

Чтобы это сделать, я изменил файл home.html:

{% extends 'blog/main.html' %}
{% block main_section %}
    {% for post in news %}
        "div class="alert alert-light""
            "h1"{{ post.title }}"/h1"
            "p"{{ post.text }}"/p"
            "span class="text-muted""Публикация: {{ post.date }}"/span"
            {% if post.author == 'Валерий' %}
                "p""b"Автор:"/b" "mark"Админ"/mark""/p"
            {% else %}
                "p""b"Автор:"/b" "mark"{{ post.author }}"/mark""/p"
            {% endif %}
        "/div"
    {% endfor %}
{% endblock main_section %}

И добавил в main.css стиль на alert-light:

.alert-light {
    border-color: #bfbfbf;
}

main.css стал выглядеть так:

body {
    background: #fafafa;
}

.alert-light {
    border-color: #bfbfbf;
}

Ещё раз просмотрите все изменения и обратите внимание на самоучитель по HTML, CSS и Bootstrap.

Часть пятая. Настройка панели администратора

Цель: Настроить панель администратора

Задачи:

  • Настройка миграции данных
  • Создание учётной записи администратора
  • Работа под учётной записью администратора

Миграция данных и создание суперпользователя

Перейдём в терминал и напишем команды:

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

Какие были диалоги:

C:\Users\Valery\PycharmProjects\MySite"python manage.py makemigrations
No changes detected

C:\Users\Valery\PycharmProjects\MySite"python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK

C:\Users\Valery\PycharmProjects\MySite"python manage.py createsuperuser
Username (leave blank to use 'valery'): Admin
Email address: portal\@miigaik.ru
Password:
Password (again):
The password is too similar to the email address.
This password is too short. It must contain at least 8 characters.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

Что мы сделали? Команда makemigrations выполнила подготовку к миграции базу данных (точнее, все баз данных). Наша база данных создалась автоматически при первом запуске сервера и файл с ней – db.sqlite3. Мы его подготовили к миграции, то есть к переходу в рабочую стезю сайта.

Вторая команда – python manage.py migrate выполнила ту самую миграцию.

Последняя команда – python manage.py createsuperuser создала суперпользователя (администратора). Мы ввели имя – Admin, почту – “portal@miigaik.ru” и пароль – miigaik.

Попробуем зайти. Для этого – запустите сервер.

Вводим адрес – “http://127.0.0.1:8000/admin

Вводим данные

Мы зашли как администратор.

Работа от имени администратора

Что мы можем сделать в панели администратора? Сверху справа мы видим кнопки – «посмотреть сайт», «сменить пароль» и «выйти». Все кнопки работают по назначению.

Мы можем создать группу или пользователя. Перейдём к пользователям

Мы видим, что сейчас создан только один пользователь – Admin

Давайте создадим ещё одного. Жмём кнопку “Add user” сверху справа.

Введём имя пользователи и пароль и нажмём кнопку «Save and continue editing». Я ввёл имя – MIIGAiK и пароль Geodez240.

Мы видим, что наш пароль зашифрован и закэширован. Также, мы можем сделать мелкую настройку – ввести личные данные, добавить пользователя в группу, отметить дату и время регистрации и т.д. Сейчас – это полностью функционирующая панель администратора, но без настроенной базы данный.

Часть шестая. Настройка базы данных

Цель: Создать и настроить базы данных

Задачи:

  • Создание файла сборки базы данных
  • Создание базы данных
  • Миграция баз данных
  • Отображение баз данных в динамическом режиме

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

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

Откроем файл models.py. Мы делаем базу данных только для приложения blog, а это значит, что и работать будем из директории приложения.

Сейчас этот файл выглядит так:

from django.db import models

# Create your models here.

Напишем небольшой код:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User


class New(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    data = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

Построчно разберёмся в коде. Первая строка – импорт модели базы данных мы не меняем. Вторая строка и вторая библиотека, которая нам понадобится – timezon. Мы будем делать вывод текущих даты и времени после написания статьи. Последняя библиотека, которая нам нужна – User. Она нужна для того, чтобы из таблички пользователей взять авторов и поместить её в новую таблицу. С библиотеками закончили. Теперь – сам класс New.

Таблица, которую мы можем увидеть в панели администратора (см. предыдущий урок) – это класс со значениями. Нам нужно сделать таблицу с четырьмя столбцами – заголовок статьи (title), текст статьи (text), дата публикации (data) и автор статьи (author). Автором может быть только тот пользователь, который есть в таблице Users.

Каждый столбец принимает отдельный тип данных. В столбце title мы будем принимать текст, максимальная длина которого – 100 символов (models.CharField(max_length=100)). То есть, мы обращаемся к библиотеке models, из неё берём объект CharField (ввод строки) и выставляем это поле на максимальную длину на 100 символов (max_length=100). В столбце text мы берём текстовое поле без ограничений в размере. Текст – html-текст. В data мы поместим дату публикации. Для этого мы вводим поле даты (DateTimeField) и выставляем значением по умолчанию текущую дату и время в часовой зоне пользователя (Django способен определять зону по IP-адресу и синхронизировать время с зоной). Последний столбец – автор публикации (author). Так как, пользователи уже созданы и находятся в таблице Users, нам не требуется заново их вводить, а нужно лишь обратиться за ключом (в каждой таблице элемент называется ключом) и вывести его. Для этого обратимся к ForeignKey. Запросим таблицу с данными – User. Если же пользователь с сайта будет удалён, мы можем вывести вместо его имени что-то (например, фразу “User deleted”) или же мы можем удалить эту запись совсем. Я выбрал удаление записи, так как оно сложнее в написании и будет этот метод выглядеть так: on_delete=models.CASCADE. Если же на нужно оставить запись и вывести фразу, то делается это так: on_delete='User deleted'. Как вы видите, ничего сложного.

Теперь выполним миграцию. Введём знакомую команду:

python manage.py makemigrations

Диалог сообщает нам о создании новой модели New:

C:\Users\Valery\PycharmProjects\MySite"python manage.py makemigrations
Migrations for 'blog':
blog\migrations\0001_initial.py
    - Create model New

Откроем в нашем приложении папку миграций: C:\Users\Valery\PycharmProjects\MySite\blog\migrations

В папке мы можем увидеть созданный нами файл – 0001_initial.py. Заглянем внутрь файла:

# Generated by Django 3.0.3 on 2020-05-20 10:35

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='New',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=100)),
                ('text', models.TextField()),
                ('data', models.DateTimeField(default=django.utils.timezone.now)),
                ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]

Файл создан Django автоматически. В классе миграции обратите внимание на список operations. Мы задали имя новой таблице и в неё ввели все данные (title, text, data, author). Плюс к этому, перед всеми элементами списка был автоматически создан элемент id. На каждом сайте все элементы должны иметь свой уникальный номер в вёрстке (id). Этот элемент создаётся Django автоматически.

Создание базы данных

Нужно понимать, что файл с расширением .py не является базой данных. Базы данных хранятся в sql-файлах. Исправим же это.

Запустим ещё пару команд:

python manage.py sqlmigrate blog 0001
python manage.py migrate

Первой командой мы запустили процесс сборки sql-файла из файла 0001_initial.py. Второй командой выполнили полную миграцию баз данных.

Диалоги:

C:\Users\Valery\PycharmProjects\MySite"python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model New
--
CREATE TABLE "blog_new" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" varchar(100) NOT NULL, "text" text NOT NULL, "data" datetime NOT NULL,
"author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY
DEFERRED);
CREATE INDEX "blog_new_author_id_eb387d4f" ON "blog_new" ("author_id");
COMMIT;

C:\Users\Valery\PycharmProjects\MySite"python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OK

Запустим сервер и проверим результат:

Как мы видим, в панели администратора ничего нет. Исправим это перейдя в файл admin.py

В нём нет ничего нужного нам для вывода:

from django.contrib import admin

# Register your models here.

Исправим это:

from django.contrib import admin
from .models import New

admin.site.register(New)

Из файла models.py мы запросили класс New и зарегистрировали его на сайте одной командой.

Проверка:

Всё работает. Обратите внимание, к каждому классу добавляется автоматически буква “s” в конце.

Добавление записей

Создадим несколько статей. Нажмём на News и в верхнем правом углу нажмём кнопку «ADD NEW»

Введём любые данные в поля и сохраним результат. Я ввёл 3 примера статей:

Динамический вывод базы данных

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

Исправим это. Зайдём в файл, который передаёт все данные на html-страницы (views.py). Мы увидим следующую картину статических данных (news):

from django.shortcuts import render

news = [
    {
        'title': 'Первая запись',
        'text': 'Много-много текста',
        'date': '10 Мая 2020',
        'author': 'Валерий'
    },
    {
        'title': 'Вторая запись',
        'text': 'Снова много-много текста',
        'date': '19 Мая 2020',
        'author': 'Егор'
    }
]


def home(request):
    data = {
        'news': news,
        'title': 'Главная страница'
    }
    return render(request, 'blog/home.html', data)


def contacts(request):
    return render(request, 'blog/contacts.html', {'title': 'Страничка про МИИГАиК'})

Исправим все данные в этом файле:

from django.shortcuts import render
from .models import New


def home(request):
    data = {
        'news': New.objects.all(),
        'title': 'Главная страница'
    }
    return render(request, 'blog/home.html', data)


def contacts(request):
    return render(request, 'blog/contacts.html', {'title': 'Страничка про МИИГАиК'})

Единственные 2 пункта, которые нужно поменять:

  • Импорт New

  • Передача всех объектов в файле New ('news': New.objects.all(),)

Проверка:

Почти победа, но исчезла дата публикации. Исправим. В файле home.py мы назвали переменную передачу даты – date, а в базе данных – data. Изменим 1 букву и получим:

{% extends 'blog/main.html' %}
{% block main_section %}
    {% for post in news %}
        "div class="alert alert-light""
            "h1"{{ post.title }}"/h1"
            "p"{{ post.text }}"/p"
            "span class="text-muted""Публикация: {{ post.data }}"/span"
            {% if post.author == 'Валерий' %}
                "p""b"Автор:"/b" "mark"Админ"/mark""/p"
            {% else %}
                "p""b"Автор:"/b" "mark"{{ post.author }}"/mark""/p"
            {% endif %}
        "/div"
    {% endfor %}
{% endblock main_section %}

Единственный момент, который сейчас не удобен и выглядит странно – дата. Во-первых, оно выглядит не красиво и во-вторых, на английском языке.

Подредактируем файл home.html, а конкретно строку:

"span class="text-muted""Публикация: {{ post.data }}"/span"

Исправим это на:

"span class="text-muted"""b"Дата:"/b" {{ post.data|date:'j F Y, время: H:i:s' }}"/span"

Все ключи я брал из документации Django – “https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#date

Результат:

Последний штрих – изменим американский «May» на русский «Май». Переходим в файл настройки всего проекта (setting.py) и найдём строку:

LANGUAGE_CODE = 'en-us'

Заменим её на:

LANGUAGE_CODE = 'ru-RU'

Результат:

Мало того, что мы изменили язык на сайте, мы ещё и перевели его панель администратора:

Часть седьмая. Деплой проекта

Цель: Выгрущить сайт в интернет

Задачи:

  • Указать три способа выгрузки сайта
  • Осуществить первый способ
  • Осуществить второй способ
  • Осуществить третий способ

Какие бывают способы деплоя?

Существует 3 способа выгрузить проект в интернет. Выгрузка проекта называется деплоем.

Способ первый. WGET.

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

  • Шаг 0 (для Windows). Скачать на компьютер wget. Это бесплатная утилита для скачивания сайтов целиком. В UNIX-образных системах она установлена.

  • Шаг 1. Запускаем сервер.

  • Шаг 2. Переходим в терминал/командную строку и пишем команду:

    wget -r -k -l 7 -p -E -nc "http://127.0.0.1:8080/"
  • Шаг 3. Заходим в папку загрузки (по умолчанию – это папка пользователя) и находим папку с проектом.

  • Шаг 4. Выгружаем папку целиком на публичный хостинг.

Способ №2. Деплой при помощи PythonAnywhere

Плюсы данного способа – полноценный деплой и простота настройки. Главный минус – использование стороннего ПО.

Есть много компаний, предоставляющих сервера в интернете. Мы воспользуемся услугами одной из них, с довольно простым процессом публикации: PythonAnywhere (“https://www.pythonanywhere.com”). PythonAnywhere бесплатен для маленьких приложений с небольшим числом посетителей, и этого будет для нас более чем достаточно.

Другим внешним сервисом, которым мы воспользуемся, будет GitHub (“https://github.com”) — сервис хостинга кода. Существуют и другие похожие сервисы, но практически у каждого программиста есть GitHub аккаунт.

В итоге код будет в трёх местах. На локальном компьютере мы будем заниматься разработкой и тестированием. Когда результат полностью устроит, мы загрузим свою программу на GitHub. А сайт будет на PythonAnywhere, и мы сможем обновлять его, просто загружая новую версию кода с GitHub.

Git

Git — это «система управления версиями», используемая множеством программистов. Эта программа отслеживает изменения, происходящие с файлами, чтобы впоследствии можно было восстановить состояние кода на нужный момент времени. Это немного похоже на функцию отслеживания изменений в Microsoft Word, но куда мощнее.

Установка Git
Windows

Вы можете загрузить Git с официального сайта git-scm.com. Можно нажимать “дальше, дальше, дальше” на всех этапах установки за исключением одного: на пятом шаге, который называется “Adjusting your PATH environment” (Настройка системной переменной Path), выберите “Use Git and optional Unix tools from the Windows Command Prompt” (Запуск Git и соответствующих Unix утилит через командную строку Windows, нижняя опция). Все остальные настройки можно оставить по умолчанию. Также неплохо будет выбрать опцию “Checkout Windows-style, commit Unix-style line endings”.

После окончания установки не забудьте перезапустить командную строку или powershell.

OS X

Загрузи Git с официального сайта git-scm.com и просто следуй инструкциям по установке.

Debian и Ubuntu
command-line
$ sudo apt install git
Fedora
command-line
$ sudo dnf install git
openSUSE
command-line
$ sudo zypper install git
Создаём Git-репозиторий

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

command-line
$ git init
Initialized empty Git repository in ~/saitMiigaika/.git/
$ git config --global user.name "Your Name"
$ git config --global user.email you@example.com

Инициализировать git-репозиторий придется только один раз за проект.

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

.gitignore
*.pyc
*~
__pycache__
myvenv
db.sqlite3
/static
.DS_Store

И сохраните его как .gitignore в корневом каталоге “saitMiigaika”.

Используйте команду git status перед git add или в любой другой момент, когда вы не уверены, что изменения — хорошая идея. Это убережёт сайт от таких неприятных сюрпризов, как добавление неправильных файлов. Команда git status возвращает информацию обо всех ранее неотслеживаемых/изменённых/добавленных в git файлах, а также статус ветки и многое другое. Результат должен быть похож на:

command-line
$ git status
On branch master

No commits yet

Untracked files:
(use "git add "file"..." to include in what will be committed)

    .gitignore
    blog/
    manage.py
    mysite/

nothing added to commit but untracked files present (use "git add" to track)

И, наконец, мы сохраним наши изменения. Переключаемся на консоль и набираем:

command-line
$ git add --all .
$ git commit -m "My Django MIIGAiK app, first commit"
[...]
13 files changed, 200 insertions(+)
create mode 100644 .gitignore
[...]
create mode 100644 mysite/wsgi.py

Загружаем код в репозиторий GitHub

Зайдите на GitHub.com и создайте новую бесплатную учётную запись.

Затем создайте новый репозиторий и назови его “my-first-blog” (к примеру). Не выбирайте опцию “initialise with a README”, не создавайте файл .gitignore (мы сделаем это локально сами) и оставьте лицензию None.

На следующем экране мы видим URL для клонирования репозитория. Выберите вариант “HTTPS” и скопируй ссылку:

Теперь нужно связать локальный репозиторий с репозиторием на GitHub.

Напечатайте у себя в консоли следующую команду (замените “github-username” на имя, указанное при создании аккаунта на GitHub, но без угловых скобок):

command-line
$ git remote add origin https://github.com/"github-username"/my-first-blog.git
$ git push -u origin master

Введите свое имя пользователя и пароль от аккаунта GitHub; мы должны увидеть примерно следующее:

command-line
Username for 'https://github.com': Username
Password for 'https://hjwp\@github.com':
Counting objects: 6, done.
Writing objects: 100% (6/6), 200 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/hjwp/my-first-blog.git
* [new branch] master -" master
Branch master set up to track remote branch master from origin.

Наш код теперь на GitHub. Зайдите на сайт и проверьте.

Настройка блога на PythonAnywhere
Регистрация на PythonAnywhere

PythonAnywhere — это сервис по запуску кода на Python в облаке. Мы будем использовать его, чтобы разместить наш сайт «вживую» в интернете.

Создайте аккаунт уровня “Beginner” на PythonAnywhere. Он бесплатный.

Создание API токена для PythonAnywhere

Это нужно будет сделать только один раз. Когда вы зарегистрируетесь на PythonAnywhere, откроется панель управления (dashboard). На ней в правом верхнем углу будет ссылка на страницу «Account»:

Там выберите вкладку «API token» и нажмите кнопку, на которой написано «Create new API token» (создать новый API token).

Настройка сайта на PythonAnywhere

Вернитесь на главную страницу PythonAnywhere, кликнув логотип. Затем запустите Bash-консоль. Нажав на кнопку bash мы запускаем командную строку, которая находится на серверах PythonAnywhere. Эта командная строка аналогична тому, что есть на компьютере.

Чтобы опубликовать сайт на PythonAnywhere, нужно загрузить на PythonAnywhere код с Github и затем настроить PythonAnywhere так, чтобы он распознал код и запустил веб-приложение. Существуют способы сделать это «вручную», но для PythonAnywhere есть программа-помощник, которая сделает это за нас. Давайте её установим.

PythonAnywhere command-line
$ pip3.6 install --user pythonanywhere

Когда мы это запустим, в консоли будет печататься лог установки. Он начнётся с чего-то вроде Collecting pythonanywhere, а последней будет строчка Successfully installed (...) pythonanywhere- (...).

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

PythonAnywhere command-line
$ pa_autoconfigure_django.py https://github.com/"github-username"/my-first-blog.git

Утилита будет печатать в консоль, что она делает:

  • Скачивает код с GitHub

  • Создаёт виртуальное окружение на PythonAnywhere, такое же, как на компьютере

  • Обновляет файл настроек с настройками деплоя

  • Создаёт базу данных на PythonAnywhere, используя команду manage.py migrate

  • Разбирается со статическими файлами

  • Настраивает PythonAnywhere так, чтобы приложение было доступно в интернете

Все эти шаги автоматизированы на PythonAnywhere, но они совершенно такие же, какие надо было бы совершить с любым другим хостинговым сервисом.

Главное, на что нужно обратить внимание сейчас, — это то, что база данных на PythonAnywhere никак не связана с базой данных на компьютере. Поэтому там будут разные посты и разные аккаунты администраторов. Как следствие, для базы на PythonAnywhere необходимо создать аккаунт администратора так же, как мы это дели локально с помощью команды createsuperuser. На PythonAnywhere заранее активировано виртуальное окружение, так что всё, что нужно сделать — это запустить в консоли PythonAnhywhere команду:

PythonAnywhere command-line
(ola.pythonanywhere.com) $ python manage.py createsuperuser

Введите параметры для своего пользователя-админа. Лучше всего использовать те же самые данные, что и на локальном компьютере, чтобы избежать путаницы.

Сейчас, если хотите, посмотрите на файлы на PythonAnywhere с помощью команды ls:

PythonAnywhere command-line
(ola.pythonanywhere.com) $ ls
blog db.sqlite3 manage.py mysite requirements.txt static
(ola.pythonanywhere.com) $ ls blog/
__init__.py __pycache__ admin.py apps.py migrations models.py tests.py views.py

Вариант 3. Без автоматизации PythonAnywhere (не рекомендуется новичку)

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

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

Предположим, у Вас куплена свежая машина, мы первый раз к ней подключаемся. Используем мы Ubuntu.

Далее буду вводить команды списком, чтобы не запутаться в шагах.

  1. Если у вас уже прописан ключ к вашей машине, но он не совпадает, очищаете его
rm .ssh/known_hosts
  1. Подключаетесь и вводите пароль от сервера.
ssh root\@5.45.120.175
  1. Обновляете пароль рута, если он вас не устраивает
passwd root
  1. Обновляем списки репозиториев.
apt-get update
  1. Апгредим.
apt-get upgrade
  1. Если присутствуют проблемы локали, исправляем их сразу.
perl -v
  1. Смотрим, если ругается и есть предупреждения генерируем локаль.
locale-gen en_US en_US.UTF-8 ru_RU.UTF-8
  1. Затем реконфигурируем локаль машины.
dpkg-reconfigure locales
  1. Вновь проверяем на наличие ошибок
perl -v
  1. Ура их нет! Двигаемся дальше. Устанавливаем Nginx.
apt-get install nginx
  1. После установки запускаем nginx.
service nginx start
  1. Смотрим статус:
service nginx status
  1. Если все ок, и он запущен можете открыть страничку вашего сайта и вы увидите стартовую страницу nginx. Если же сервер не запустился, проверте, не запущен ли у вас apache
service apache2 status
  1. Если он запущен стопайте его. Его необходимо полностью удалить.
service apache2 stop
  1. Деинсталируем апач и все его конфиги такой вот не хитрой командой:
apt-get purge apache2 apache2-utils apache2.2-bin apache2-common
  1. Если какие то пакеты, которые собираемся удалить отсутствуют, просто уберите их из команды. Далее:
apt-get autoremove
  1. Наконец, надо проверить наличие конфигурационных файлов или мануалов, связанных с Apache2, но до сих пор не удаленных.
whereis apache2
  1. Удаляете все эти директории вручную. Например, вот так:
rm -rf /etc/apache2
  1. Если все удалено, аллилуя. Запускаем nginx. И смотрим статус:
service nginx start
service nginx status
  1. Если все ок, заходите на вашу страничку и вы увидете стартовую страницу nginx. Идем дальше. Cоздайте пользователя для старта django-приложения. Создайте из-под него виртуальное окружение.
apt-get install python3-dev python3-setuptools
easy_install-3.4 virtualenv
adduser django
login django
cd /home/django
virtualenv venv
  1. Теперь, переносим проект в эту папку.Устанавливаем git, nano если они не установлены.
apt-get install git nano
  1. Создаем ключ ssh. Все поля оставляем пустыми.
ssh-keygen -t rsa -C "your_mail\@mail.com"
  1. Переходим в директорию ключа, открываем необходимый нам публичный ключ. Советую с помощью утилиты sshfs подключиться к вашей машине через gui интерфейс. Вам будет необходимо указать адрес машины и папку, в которую поместите файлы машины. Например вот так.
sshfs root@5.45.120.175:/ /home/user/Develop/sites/my_site/
  1. Затем копируете ключ.
/root/.ssh/id_rsa.pub
  1. Копируем его в настройки пользователя git репозитория

  2. После того, как вы это сделаете, вы сможете спокойно клонировать по ssh репозиторий. Заходите под рутом.

su - root
cd /home/django/
git clone git@github.com:user/my_site.git
  1. Симлинк /etc/nginx/sites-enabled/default можно удалить

  2. Логинимся под юзером django.

login django
  1. Активируем виртуальное окружение.
source venv/bin/activate
  1. Устанавливаем Django в наше виртуальное окружене:
pip install Django
  1. Переходим в корневую папку проекта.
cd my_site
  1. Один из хороших способов установить uWSGI:
pip install uwsgi
  1. Проверка. Создаем файл test.py:
nano test.py
  1. С таким содержимым:(Если не создается, создайте от рута)
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
  1. Запускаем uWSGI:
uwsgi --http :8000 --wsgi-file test.py
  1. Если все работает, нажимаем ctrl-c, завершая процесс и продолжаем дальше.

  2. Теперь конфигурируем наш сайт. Устанавливаем postgresql. Из под рута.

apt-get install libpq-dev postgresql postgresql-contrib
su - postgres
createdb my_site
createuser -P django
psql
postgres=# GRANT ALL PRIVILEGES ON DATABASE my_site TO django;
su - root
login django
source /home/django/venv/bin/activate
pip install psycopg2
  1. Если необходимо перенести БД со старой на новую делается это так:
  • Шаг 1. Выполняется со старыми настройками DATABASES в settings.py python manage.py dumpdata ” datadump.json
  • Шаг 2. Выполняется с новыми настройками DATABASES в settings.py python manage.py loaddata datadump.json
  1. После этого устанавливаем все библиотеки что есть в requirements.txt. Для этого заходим в папку my_site проектом и вводим следующую команду. Разумеется с помощью виртуального окружения.
pip install -r requirements.txt
  1. Если не установилась какая-нибудь библиотека X устанавливайте более позднюю версию:
pip install X==2.9.0
  1. В файле …/my_site/settings.py обязательно нужно указать настройки базы данных:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'my_site',
        'USER': 'django',
        'PASSWORD': '1234567890',
        'HOST': 'localhost',
        'PORT': '',
    }
}
  1. В файле settings.py должен быть такой путь:
MEDIA_ROOT = "/home/django/my_site/media"
  1. Делаем миграцию, если это необходимо:
python manage.py migrate
  1. Создаем супер пользователя.
python manage.py createsuperuser
  1. Запускаем сервер
python manage.py runserver 0.0.0.0:8080
  1. Если ошибок не возникло, заходим и настраиваем сайт через панель администратора (если у вас новая свежая база данных без данных).

  2. После того, как вы сконфигурировали проект идем дальше. Собираем всю статику (Скорее всего это сработает только из под рута):

python manage.py collectstatic
  1. Теперь, вы можете запустить my_site через uwsgi, и если это не сработало, значит вы где то совершили ошибку. Вполне вероятно, о ней сообщат логи uwsgi.
uwsgi --http :8000 --module my_site.wsgi
  1. Теперь нам необходимо сконфигурировать nginx. Для начала, создайте файл в корне проекта my_site с названием uwsgi_params, с таким содержанием:
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
  1. Вообще, лучше поместите этот файл в корень проекта, в папку с названием deployment, чтобы файлы проекта различались с файлами деплоя.

  2. Теперь в той же папке создайте файл my_site_nginx.conf

  3. Наполните его таким содержимым:

# the upstream component nginx needs to connect to
upstream django {
    server unix:///home/django/my_site/uwsgi_nginx.sock; # for a file socket
    # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen 8000;
    # the domain name it will serve for
    server_name my_site.ru; # substitute your machine's IP address or FQDN
    charset utf-8;

    # max upload size
    client_max_body_size 75M; # adjust to taste

    # Django media
    location /media {
        alias /home/django/my_site/media; # your Django project's media files - amend as required
    }

    location /static {
    alias /home/django/my_site/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass django;
        include /home/django/my_site/deployment/uwsgi_params; # the uwsgi_params file you installed
    }
}
  1. В папке /etc/nginx/sites-enabled создаем ссылку на файл mysite_nginx.conf, чтобы nginx увидел его.
sudo ln -s /home/django/rss_news/deployment/rss_news_nginx.conf /etc/nginx/sites-enabled
  1. Перезапускаем nginx:
/etc/init.d/nginx restart
  1. Помещаем файл с именем, например, media.png в папку /home/django/my_site/media.

  2. В браузере переходим по адресу yourserver.com:8000/media/media.png и, если видим наш файл, значит мы все сделали правильно.

  3. Пробуем запустить через сокет:

uwsgi --socket uwsgi_nginx.sock --wsgi-file test.py —-chmod-socket=666
  1. nginx + uWSGI + Django. Запускаем: В браузере переходим на yourserver.com:8000/ и видим стартовую страницу Django.
uwsgi --socket uwsgi_nginx.sock --module my_site.wsgi --chmod-socket=666
  1. Мы собрали всю цепочку, но настройка еще не закончена, идем дальше.

  2. Очень удобно все опции, с которыми мы запускаем uWSGI, указать в ini файле, а при запуске передавать только путь к этому файлу. Создаем файл my_site_uwsgi.ini в нашей папке deployment. Указываем в нем следующее содержимое:

#mysite_uwsgi.ini
[uwsgi]

# Настройки, связанные с Django
# Корневая папка проекта (полный путь)
chdir = /home/django/my_site
# Django wsgi файл
module = my_site.wsgi
# полный путь к виртуальному окружению
home = /home/django/venv
# общие настройки
# master
master = true
# максимальное количество процессов
processes = 10
# полный путь к файлу сокета
socket = /home/django/my_site/uwsgi_nginx.sock
# права доступа к файлу сокета
chmod-socket = 666
# очищать окружение от служебных файлов uwsgi по завершению
vacuum = true
env = DEBUG_MODE=False
daemonize=/var/log/uwsgi/my_site.log
  1. Запускаем этот файл:
uwsgi --ini my_site_uwsgi.ini
  1. Проверяем. Все работает? Дальше. До сих пор uWSGI был установлен в виртуальном окружении. Чтобы была возможность автоматически запускать uWSGI при старте операционной системы, мы установим его глобально. Деактивируем виртуальное окружение:
deactivate
  1. Устанавливаем pip и pip3 глобально.
apt-get install python-pip python3-pip
  1. Затем, устанавливаем uwsgi глобально.
pip3 install uwsgi
  1. Проверяем запуск:
uwsgi --ini my_site_uwsgi.ini
  1. Если сервер обслуживает несколько проектов, каждый из которых использует uWSGI, то нужно использовать режим Emperor. В этом режиме uWSGI просматривает папку с конфигурационными файлами и для каждого файла запускает отдельный процесс (вассал).

    Если один из конфигурационных файлов будет изменен, uWSGI перезапустит соответствующего вассала.

    Создаем папку для конфигурационных файлов:

sudo mkdir /etc/uwsgi

sudo mkdir /etc/uwsgi/vassals
  1. Создаем в ней ссылку на my_site_uwsgi.ini:
sudo ln -s /home/django/my_site/deployment/my_site_uwsgi.ini /etc/uwsgi/vassals/
  1. Запускаем uWSGI в режиме Emperor, потом отключаем если все работает (Возможно вам придется перезапустить вашу БД такой командой sudo service postgresql restart):
uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
  1. Устанавливаем супервизор
apt-get install supervisor
  1. Создаем файл конфигурации в папке etc/supervisor/conf.d/my_site.conf:
echo_supervisord_conf " /etc/supervisord.conf
  1. В Этом файле указываем следующий текст:
[program:my_site]
command=uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
stdout_logfile=/home/django/my_site/deployment/uwsgi.log
stderr_logfile=/home/django/my_site/deployment/uwsgi_err.log
autostart=true
autorestart=true
  1. Индексируем этот файл: (Если появляются какие то ошибки, перезапускаем supervisor (service supervisor restart)) Так же, смотрим логи.
supervisorctl reread
supervisorctl update
  1. Все должно работать. Управлять supervisor можно как сервисом:
service supervisor start|stop|status ...
  1. Если происходят какие то изменения в коде, выполняем эту команду в папке deployment:
service supervisor stop
touch my_site_uwsgi.ini
service supervisor start
  1. Команда supervisorctl покажет запущенные приложения императором.

  2. Если необходимо запустить проект в режиме дебага, меняем значение DEBUG_MODE=False на DEBUG_MODE=True в файле конфигурации uwsgi.

  3. Готово!