Язык программирования Python

Курс IT-Академии Сухорукова

Январь-март 2019

Этот курс закончился

Задание. Клон Twitter

Создадим простой микроблог-сервис, похожий на всем известный Twitter. Делать это мы будем, конечно, средствами Django.

Постановка задачи

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

Каждая публикация содержит текст сообщения (ограниченный по длине), а так же у неё есть дата и время создания и автор. Автор — это пользователь нашего сервися (воспользуемся стандартным классом User, который предоставляет нам приложение django.contrib.auth). Кроме того, есть понятие «Подписка». Подписка — это связь между двумя пользователями, один из них — подписчик (follower), второй — автор (author). Существование такой связи означает, что подписчик в ленте публикаций будет видеть публикации автора. Один автор может иметь множество подписчиков, подписчик может быть подписан на множество авторов. Любой пользователь может быть автором, подписчиком, или и тем, и другим сразу.

Соответственно, сервис должен реализовывать следующее:

  • Регистрация пользователя, вход в систему
  • Страница пользователя
  • Лента публикаций
  • Форма создания публикации
  • Просмотр списка подписчиков пользователя
  • Просмотр списка авторов, на которых подписан пользователь
  • Создание подписки
  • Удаление подписки («отписка»)

Примеры страниц

Примеры html-страниц и готовое представление для регистрации нового пользователя можно взять по этой ссылке.

Подробности

Регистрация и вход в систему

Для этих целей можно воспользоваться стандартными представлениями из поставки Django. Кроме формы регистрации, конечно. Остальные действия: вход в систему, восстановление пароля и прочее уже реализованы.

Форма регистрации вместе с обрабатывающим её представлением есть в приложенном архиве.

Страница пользователя (профиль)

На этой странице отображаются сколько-то последних публикаций пользователя, а так же его имя, количество подписок и подписчиков. Кроме того, тут же находится ссылка «Подписаться» / «Отписаться», которая создаёт или удаляет подписку текущего пользователя с указанным. Конечно, нельзя подписаться на себя, а так же нельзя подписаться, если текущего пользователя нет (пользователь не авторизован).

Лента публикаций

Лента представляет собой просто последовательность публикаций, отсортированных в хронологическом порядке (по убыванию, от новых к старым). В ленте показываются только публикации, авторы которых входят в список авторов, на которых подписан текущий пользователь. Для неавторизованного пользователя лента недоступна.

Основная сложность тут — выполнить запрос к моделям. Напоминаю, что есть lookup-выражение __in, которое может параметром принимать как список, так и QuerySet.

Форма создания публикации

Тут всё тривиально. У формы одно-единственное поле «Текст публикации» и кнопка «Опубликовать» типа submit.

Просмотр списка подписчиков и списка авторов

Это просто страницы с именем выбранного пользователя и списком его подписчиков (или авторов, на которых он подписан). У этих страниц будут URL вида profile/ИМЯ/followers и profile/ИМЯ/following, где ИМЯ — это имя пользователя, подписки или подписчиков которого мы хотим видеть. Просматривать эту информацию могут и неавторизованные пользователи.

Создание и удаление подписки

Когда авторизованный пользователь попадает на страницу профиля другого пользователя (назовём его автор), на которого оно не подписан, он видит там ссылку «Подписаться». Переход по этой ссылке вызывает создание подписки, в которой подписчиком будет текущий пользователь, а автором — пользователь, на чей профиль он сейчас смотрит. После чего происходит перенаправление обратно на страницу профиля автора.

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

Роутинг

Адрес Представление
"" Главная страница, предложение «войдите или зарегиструйтесь» для анонимного пользователя, либо лента новостей для зарегистрированного.
"post/" Форма написания новой публикации. Доступно только для зарегистрированных пользователей.
"user/<str:username>/" Профиль указанного пользователя. Доступно и для зарегистрированных, и для незарегистрированных пользователей.
"user/<str:username>/subscribe/" Ссылка для подписки текущего пользователя на пользователя username. Создаёт подписку, после чего перенаправляет обратно на профиль пользователя username.
"user/<str:username>/unsubscribe/" Ссылка для удаления подписки текущего пользователя на пользователя username. Удаляет подписку, после чего перенаправляет обратно на профиль пользователя username.
"user/<str:username>/following/" Список подписок пользователя username.
"user/<str:username>/followers/" Список подписчиков пользователя username.
"accounts/login/" Форма входа на сайт *
"accounts/logout/" Выход с сайта *
"accounts/password_change/" Форма смены пароля *
"accounts/password_change/done/" Страница с сообщением об успешной смене пароля *
"accounts/password_reset/" Форма восстановления забытого пароля *
"accounts/password_reset/done/" Сообщение о том, что на E-Mail пользователя отправлено письмо с инструкциями по восстановлению пароля *
"accounts/reset/<str:uidb64>/<str:token>/" Уникальная ссылка на форму для восстановления пароля *
"accounts/reset/done/" Сообщение о том, что забытый пароль успешно восстановлен *
"accounts/profile/" Форма настройки профиля текущего пользователя. Ввод имени, email, ссылка на смену пароля. Я бы не разрешил менять логин (username), но как хотите.

Помеченные звёздочкой (*) представления — это стандартные представления из приложения django.contrib.auth. Почитать о них можно в документации (к сожалению, я не смог найти годных материалов на русском языке по этой теме, наверное, пора самому писать).

В приложенном архиве есть примеры реализации шаблонов для этой системы.

Настройка отправки электронной почты

Django умеет отправлять электронную почту от имени вашего сайта, но ей понадобится уже существующий зарегистрированный почтовый ящик для этих целей. Часто хостинг-провайдер вместе с размещением вашего сайта предоставляет вам личный почтовый сервер с адресами вида _любой-адрес@домен-вашего-сайта.ru_. Если это не так (например, вы пользуетесь бесплатным хостингом), вы можете воспользоваться любым почтовым сервисом — GMail, Mail.ru, Yandex и так далее. Однако, например, на хостинге PythonAnywhere вам будет доступен только GMail. Для GMail-ящика укажите следующие настройки:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'ВАШ-ЛОГИН@gmail.com'
EMAIL_HOST_PASSWORD = 'ВАШ-ПАРОЛЬ-ОТ-ПОЧТЫ'
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = 'ВАШ-ЛОГИН@gmail.com'

Для любого другого почтового сервиса настройки аналогичные, узнайте, какой адрес, номер порта и параметры входа у SMTP-сервера этого почтового сервиса. Например, для сервиса Почта НГС эта информация доступна в справке. Теперь система восстановления пароля будет работать. Если всё же письма не отправляются, проверьте на локальном сервере (python manage.py runserver). Если с локального сервера всё работает, а на PythonAnywhere — нет, обратитесь к справочной информации тут.