Создаем блог на Django с опросами и тестами. Краткая инструкция. Часть 1

-jvwu-uybeevfito-53h-nvesym.gif


Самый действенный способ изучить фреймворк — написать пет-проект. Например, свою социальную платформу на Django. Во время реализации можно попрактиковаться в работе с формами, представлениями, сигналами и SMTP.

В Proglib собрали небольшой шаблон, на базе которого можно создать свой блог на Django, а после — задеплоить на виртуальный сервер. Материал будет полезен новичкам, которые знакомы с базовыми концепциями фреймворка и хотят закрепить знания. Подробности под катом!

Разделяй и властвуй


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

Исходный код проекта находится в репозитории. Делайте форк и предлагайте свои улучшения!


Используйте навигацию, если не хотите читать статью полностью:

Структура и функционал проекта


9hz4ksbxrogicluy2b4p8ick1nk.png


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

  • 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


sopqxhkce7xvznqw1oqqvft9psc.png


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

manage.py startapp users


Также важно зарегистрировать новое приложение в корневой директории проекта, в конфигурационном файле settings.py.

vrfv9v8bzmfqx7jkw1tycqqvkzk.png

Чтобы пользователь мог подключиться к приложению, нужно настроить маршрутизацию — перейти в корневую директорию проекта и зарегистрировать пути в конфигурационном файле 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


ilgovnm8txnlmjl5dqkxmhh5hco.png


После добавления пользовательского функционала можно перейти к основному приложению — 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.


k5h7xuqzyygjvfyumceelhmk65q.png

Тестовый запуск блога на сервере


Супер — большая часть функциональности уже готова. Можно загрузить код на сервер и протестировать работу приложения в продакшн-среде. Так оно будет доступно 24/7 вне зависимости от того, включена локальная машина или нет.

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

Создаем сервер и настраиваем конфигурацию. Минимальный вариант — 20% vCPU, 1 ГБ ОЗУ, базовый SSD-диск на 5 ГБ и Ubuntu в качестве операционной системы. С учетом публичного IP-адреса такая конфигурация выйдет примерно 25 рублей в день.

idpthvoapshfjniuw6yfcxlowm8.png

Подготовка операционной системы и окружения


Для начала обновим 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 
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.

vnm-vdexhnl0uyffkeh3wn1nydy.png


Однако стандартный веб-сервер Django предназначен только для тестирования и запуска веб-приложений во время разработки. Для обработки запросов в продакшене нужен Nginx и WSGI Gunicorn. В следующей статье подробно разберем, как их настроить.

Возможно, эти тексты тоже вас заинтересуют:

→ Простая процедурная генерация мира, или Шумы Перлина на Python
→ «Карманный синоптик за час». Пишем Telegram-бота для мониторинга погоды на Python
→ Проверяем ветхозаветную историю происхождения человечества от Адама и Евы с помощью популяционной модели

© Habrahabr.ru