Эмуляция почтового сервера в Django

Пользователи любого сервиса всегда теряют, забывают или компрометируют свои пароли: таково их неотъемлемое свойство. Поэтому в модуль django.contib.auth встроен сценарий восстановление пароля: пользователь отправляет через специальную веб-форму свой email, и если этот адрес есть в базе, ему уходит письмо с инструкцией по восстановлению.

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

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

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

Сохранение писем в файлы

В Django есть несколько модулей для отправки писем, подключить их можно через ключ конфигурации EMAIL_BACKEND в settings.py:

PYTHONEMAIL_BACKEND = 'django.core.mail.backends.XXX' 

Вместо XXX указывается название модуля. Встроенные в Django почтовые модули могут отправлять почту по протоколу SMTP, выводить в консоль содержимое письма, сохранять письма в файлы, хранить их в памяти или просто ничего не делать (даже для «ничего не делать» написан специальный модуль).

Подключите к проекту модуль filebased.EmailBackend: он будет сохранять текст отправленных электронных писем в файлы в отдельную директорию.Добавьте в settings.py такой код:

#  подключаем движок filebased.EmailBackend
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
# указываем директорию, в которую будут складываться файлы писем
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'sent_emails') 

Создайте папку /sent_emails в головной директории проекта.

Теперь при запросе на восстановление пароля система будет делать вид, что отправила письмо, но эти письма будут «отправляться» в директорию sent_emails. Если эта директория не существует, она будет создана после первого «письма».

Пройдите процедуру восстановления пароля для своего аккаунта. Если вы всё настроили правильно — в sent_emails будут созданы файлы с текстом уведомления. Вот тут:

└── yatube
    ├── core
    ├── posts
    ├── sent_emails  <-- Директория для хранения писем
    ├── templates
    ├── users   
    └── manage.py 

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

Делать не нужно, но знать полезно

Для работы с почтой в Django есть специальный модуль Mail, отправкой писем занимаются функции из этого модуля:

  • send_mail() — для отправки единичного письма получателю.
  • send_mass_mail() — для отправки множества писем.
  • mail_admins — отправить письмо администраторам сайта. Список адресов администраторов перечисляется в списке ADMINS в settings.py.
  • mail_managers — для отправки писем менеджерам сайта. Большой проект может управляться большим количеством сотрудников, и в списке MANAGERS конфига можно задать список их почтовых адресов, по которым будет идти служебная рассылка.

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

Самый простой способ отправить письмо из собственной view-функции или класса — вызвать стандартную функцию Django send_mail() и передать ей на вход необходимые данные:

from django.core.mail import send_mail

send_mail(
    'Тема письма',
    'Текст письма.',
    'from@example.com',  # Это поле "От кого"
    ['to@example.com'],  # Это поле "Кому" (можно указать список адресов)
    fail_silently=False, # Сообщать об ошибках («молчать ли об ошибках?»)
) 




Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: