Как создать блог на Django с опросами и тестами. Часть 1
Рассказываем, как создать многофункциональную социальную платформу и развернуть готовое приложение на сервере.
Введение
Нам предстоит собрать и запустить довольно большой проект, поэтому мы решили разделить материал на две статьи. В этой части сделаем обзор шаблона, в котором реализована основная функциональность платформы, и покажем, как выбрать хостинг. В следующей — как развернуть веб-приложение с помощью Nginx и Gunicorn. Что из этого получится, можно посмотреть по ссылке.
Исходный код проекта находится в репозитории. Делайте форк и предлагайте свои улучшения!
Структура и функциональность проекта
На этапе проектирования важно разбить проект на самостоятельные приложения. Базово в блоге есть сервисы для аутентификации и авторизации, управления записями, опросами и тестами. Итого четыре приложения:
- users — аутентификация, авторизация, создание и редактирование профилей. Подписка на блоги, мессенджер, обработка контактной формы, поиск пользователей по интересам и ключевым словам.
- blog — создание, редактирование и удаление записей. Лайки, закладки, рекомендации, комментарии, сортировка записей по категориям и тегам. Поиск по ключевым словам в записях пользователей.
- polls — проведение опросов и голосований. Визуализация реализована с помощью библиотеки Chart.js.
- quizzes — модуль для создания и проведения тестов. Поддерживаются два типа вопросов — с единственным правильным и несколькими ответами.
Инициализируем проект
Начнем с самого простого: создадим виртуальное окружение, установим необходимые зависимости для среды разработки и инициализируем проект.
python -m venv blogit\venv
cd blogit
venv\scripts\activate
Установить зависимости можно с помощью requirements.txt — он содержит список необходимых модулей. Файл доступен по ссылке.
pip install -r requirements.txt
Вместе со всеми модулями pip подтягивает основной — django. Теперь можно создать проект.
django-admin startproject config .
Точка в конце команды нужна, чтобы директория проекта config и управляющий скрипт manage.py находились на одном уровне с директориями приложений.
Каждое приложение будет содержать внутри своей директории набор html-шаблонов, которые будет возвращать Django в ответ на сетевые запросы. Но также есть несколько базовых и универсальных шаблонов, к которым должны иметь доступ все приложения — они расположены в папке templates внутри корневой директории проекта:
- base.html — базовый шаблон проекта, в котором подключаются статические файлы, иконки и внешние скрипты.
- delete_template.html — удаление объектов (записей, интересов и так далее).
- landing.html — главная страница платформы, которая видна только неавторизованным пользователям.
- navbar.html — меню с разделами сайта.
- pagination.html — универсальный шаблон для постраничного вывода любых объектов – от профилей и записей до опросов и тестов.
- socials.html — ссылки на аккаунты в соцсетях.
- tags_categories.html — вывод тегов и категорий записей.
Приложение users
В приложении users сосредоточена вся функциональность, связанная с созданием и обслуживанием пользовательских профилей. Чтобы его создать, нужно запустить управляющий скрипт с соответствующими параметрами.
manage.py startapp users
Также важно зарегистрировать новое приложение в корневой директории проекта, в конфигурационном файле settings.py.
Чтобы пользователь мог подключиться к приложению, нужно настроить маршрутизацию — перейти в корневую директорию проекта и зарегистрировать пути в конфигурационном файле urls.py.
path('', include('users.urls')),
Собственные маршруты приложения users будут храниться в файле users/urls.py — их можно найти и модифицировать по ссылке.
Шаблоны users расположены в отдельной директории — users/templates/users:
- account.html — загружает собственный профиль авторизованного пользователя для редактирования.
- friends.html — выводит карточки с профилями друзей пользователя.
- inbox.html — страница с входящими сообщениями.
- interest_form.html — добавление нового интереса.
- login_register.html — регистрация / вход на сайт.
- message.html — вывод текста полученного сообщения.
- message_form.html — создание нового сообщения.
- profile_form.html — форма для добавления дополнительной информации, на которую пользователь перенаправляется сразу после регистрации.
- profiles.html — вывод профилей всех зарегистрированных пользователей с возможностью поиска по именам, интересам и ключевым словам в тексте «Обо мне».
- user-profile.html — просмотр профиля любого пользователя.
Вся логика для создания, редактирования и удаления профилей находится в signals.py. В файле utils.py расположены функции для пагинации и поиска по профилям. Обратите внимание, что система поиска игнорирует профиль авторизованного пользователя, а функция пагинации является универсальной: она используется в других приложения блога для постраничного вывода записей, тестов и опросов. В файле users/forms.py расположены формы для регистрации и редактирования профиля, создания интересов и сообщений.
Модели в файле users/models.py описывают таблицы базы данных, которые связаны с хранением пользовательских профилей, интересов и сообщений. Слаги для интересов создаются автоматически: для транслитерации кириллицы используется функция slugify из модуля pytils.translit.
Функции представления users описаны в users/views.py — они обеспечивают:
- регистрацию, аутентификацию и авторизацию пользователей,
- добавление пользователей в друзья (и удаление из друзей),
- создание и отправку сообщений,
- редактирование профиля и интересов,
- сортировку профилей по определенному интересу,
- отправку сообщения из контактной формы с помощью SMTP.
Приложение блога
После добавления пользовательского функционала можно перейти к основному приложению — blog. Аналогичным образом создаем его, регистрируем в settings.py и инициализируем в urls.py корневой директории. Маршруты самого блога находятся в blog/urls.py, а шаблоны — в blog/templates/blog.
- my-blog.html — шаблон для отображения собственного блога авторизованного пользователя.
- post_footer.html — футер поста для вывода количества лайков, закладок и комментариев.
- post_form.html — шаблон с формой добавления новой записи.
- post_list.html — «френдлента» и вывод записей по категориям и тегам.
- single-post.html — вывод отдельного поста с комментариями.
- user-blog.html — вывод блога любого пользователя.
Во время создания и редактирования записи пользователи могут выбирать существующие теги или добавлять новые: слаги для тегов создаются автоматически с помощью ранее упомянутого модуля pytils.translit. Метод генерации слагов get_unique_slug() для записей класса Post обеспечивает уникальность ссылок: если подобный слаг уже существует, к новому будет добавлен соответствующий порядковый номер:
def get_unique_slug(self):
slug = slugify(self.title)
unique_slug = slug
num = 1
while Post.objects.filter(slug=unique_slug).exists():
unique_slug = f"{slug}{num}"
num += 1
return unique_slug
Функция генерации уникального слага.
У класса Post есть и другие полезные методы:
- number_of_likes() — возвращает число лайков.
number_of_bookmarks()
— подсчитывает, сколько раз пользователи добавили запись в закладки.
number_of_comments()
— определяет число одобренных и опубликованных комментариев. За одобрение комментариев отвечает метод approve() класса Comment.
Вся логика блога описана в blog/views.py. Функции представления отвечают за:
- добавление и удаление лайков и закладок,
- сортировку записей по тегам и категориям,
- вывод записей, добавленных в избранное, или отмеченных лайком,
- постраничный вывод записей и поиск по ключевым словам. Сам поиск записей реализован с помощью модуля Django Q — соответствующая функция описана в blog/utils.py.
Тестовый запуск блога на сервере
Супер — большая часть функциональности уже готова. Можно загрузить код на сервер и протестировать работу приложения в продакшн-среде. Так оно будет доступно 24/7 вне зависимости от того, включена локальная машина или нет.
На первых порах, когда пользователей у проекта еще мало, будет достаточно виртуального сервера с гибкой производительностью ядра. Для этого регистрируемся и входим в панель управления my.selectel.ru. Переходим в раздел Облачная платформа и выбираем Серверы.
Создаем сервер и настраиваем конфигурацию. Минимальный вариант — 20% vCPU, 1 ГБ ОЗУ, базовый SSD-диск на 5 ГБ и Ubuntu в качестве операционной системы. С учетом публичного IP-адреса такая конфигурация выйдет примерно 25 рублей в день.
Нажмите на бургер-меню в левом верхнем углу и перейдите в раздел Облачная платформа. Затем создайте новый проект.
Подготовка операционной системы и окружения
Для начала обновим Ubuntu, установим Git, Python, Nginx, файервол и вспомогательный пакет python3-dev. А также создадим виртуальное окружение и активируем его.
sudo apt upgrade
sudo apt install git ufw python3-pip python3-dev nginx
sudo apt install python3-venv
python3 -m venv blogitenv
source blogitenv/bin/activate
Теперь клонируем репозиторий, предварительно загруженный на GitHub, и установим необходимые зависимости.
git clone https://github.com/natkaida/blogit.git
cd blogit
pip install -r requirements.txt
Далее нужно перейти в settings.py и установить значение False для параметра DEBUG. А в ALLOWED_HOSTS — добавить локальный и публичный адреса сервера, по которым будет доступен блог. Также не забудьте изменить значение SECRET_KEY и проверить конфигурации, которые используют приложения.
DEBUG = False
ALLOWED_HOSTS = ['94.26.224.162', 'localhost']
/root/blogit/config/settings.py
Настройка проекта и запуск
Теперь можно создать базу данных, аккаунт суперпользователя/администратора и собрать статические файлы в папку static, откуда их позже будет раздавать Nginx.
python3 manage.py migrate
python3 manage.py createsuperuser
python3 manage.py collectstatic
Пора проверить, как прошла установка приложения. Для этого запустим проект на нативном веб-сервере Django со специальным параметром --insecure
, который позволяет фреймворку раздавать статические файлы в режиме DEBUG = False
.
python3 manage.py runserver 0.0.0.0:8000 --insecure
Готово — сайт доступен из интернета по адресу http://94.26.224.162:8000.
Однако стандартный веб-сервер Django предназначен только для тестирования и запуска веб-приложений во время разработки. Для обработки запросов в продакшене нужен Nginx и WSGI Gunicorn.
Заключение
В этой части мы разобрали шаблон, в котором реализована основная функциональность платформы, и коснулись вопроса выбора хостинга. В следующей — расскажем, как настроить Nginx и Gunicorn для веб-приложения и развернуть почтовый сервер.