В этом материале создадим простую контактную форму для отправки электронных сообщений с сайта Django 3.0. Воспользуемся возможностями встроенной поддержки email, что позволит без лишних усилий отправлять электронные сообщения, используя сервис SendGrid.
Архив с проектом contact.rar
Первоначальная настройка
Если вы уже знаете как создавать джанго-приложение, этот шаг можно пропустить. Создайте проект —
config
, приложение —sendemail
и виртуальное окружениеcontact
.
Первый шаг — создание отдельной папки для проекта. Создайте ее в ручную или с помощью терминала. В командной строке (Mаc или Linux, для Windows некоторые команды отличаются) выполните следующие команды, чтобы перейти в нужную директорию и создать новую папку «contact».
$ cd ~/ПУТЬ_К_ПАПКЕ
$ mkdir contact && cd contact
Теперь можно установить Django и активировать виртуальную среду.
Примечание:
Естьpipenv
у вас не установлен, начните сpip install pipenv
$ pipenv install django==3.0.5
$ pipenv shell
Далее создадим новый проект Django под названием config
в приложении sendemail
:
(contact) $ django-admin startproject config .
(contact) $ python manage.py startapp sendemail
Чтобы убедиться, что все работает, запустим migrate
и runserver
.
(contact) $ python manage.py migrate
(contact) $ python manage.py runserver
Если теперь открыть ссылку 127.0.0.1:8000, то должно появиться приблизительно следующее:
Обновление settings.py
Созданное приложение теперь нужно явно добавить в проект Django. В файле settings.py
следует записать sendemail
в разделе INSTALLED_APPS
.
# config/settings.py
INSTALLED_APPS [
'sendemail.apps.SendemailConfig', # новая строка
...
]
Затем в этом же файле нужно создать DEFAULT_FROM_EMAIL
— ваша@почта.com и RECIPIENTS_EMAIL
— список почт получателей по уполчанию. Также стоит обновить EMAIL_BACKEND
, указав, какой бэкенд email используется — в данном случае это console
. Это нужно, чтобы почта выводилась в командной строке.
# config/settings.py
RECIPIENTS_EMAIL = ['manager@mysite.com'] # замените на свою почту
DEFAULT_FROM_EMAIL = 'admin@mysite.com' # замените на свою почту
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Обновление urls.py
После добавления приложения в проект Django нужно обновить корневой файл config/urls.py
, добавив include
в верхней строке, а также новый urlpattern
в приложении:
# config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sendemail.urls')),
]
Дальше создайте файл sendemail/urls.py
в приложении вручную или:
touch sendemail/urls.py
Теперь — этот код. Благодаря ему основная контактная форма будет доступна по ссылке email/
, а удачная отправка — перенаправлять на success/
.
# sendemail/urls.py
from django.contrib import admin
from django.urls import path
from .views import contact_view, success_view
urlpatterns = [
path('contact/', contact_view, name='contact'),
path('success/', success_view, name='success'),
]
Создание forms.py
Внутри приложения sendemail
теперь нужно создать новый файл forms.py
.
touch sendemail/forms.py
Он будет содержать все поля для самой формы. Потребуются три: from_email
, subject
и message
.
# sendemail/forms.py
from django import forms
class ContactForm(forms.Form):
from_email = forms.EmailField(label='Email', required=True)
subject = forms.CharField(label='Тема', required=True)
message = forms.CharField(label='Сообщение', widget=forms.Textarea, required=True)
Будем использовать встроенный в Django Forms API для быстрого создания трех полей.
Создание views.py
Создадим представление, которое будет выполнять основную работу для контактной формы. Обновим существующий файл sendemail/views.py
:
from django.shortcuts import render
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
from config.settings import RECIPIENTS_EMAIL, DEFAULT_FROM_EMAIL
def contact_view(request):
# если метод GET, вернем форму
if request.method == 'GET':
form = ContactForm()
elif request.method == 'POST':
# если метод POST, проверим форму и отправим письмо
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(f'{subject} от {from_email}', message,
DEFAULT_FROM_EMAIL, RECIPIENTS_EMAIL)
except BadHeaderError:
return HttpResponse('Ошибка в теме письма.')
return redirect('success')
else:
return HttpResponse('Неверный запрос.')
return render(request, "email.html", {'form': form})
def success_view(request):
return HttpResponse('Приняли! Спасибо за вашу заявку.')
Сначала импортируем send_email
и BadHeaderError
для безопасности. После этого добавим ссылку на класс ContactForm
, который был создан в файле forms.py
.
Создание шаблонов
В качестве финального шага нужно создать шаблоны для сообщения и страницы с информацией об успешной отправке. Для этого используем новую папку templates
в директории с проектом.
(contact) $ mkdir templates
(contact) $ touch templates/email.html
Теперь обновим файл settings.py
, чтобы Django знал, где искать папку с шаблонами. Обновим настройку DIRS
в TEMPLATES
.
# config/settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
},
]
Далее обновим сами файлы шаблонов, используя следующий код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Пример отправки сообщений</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<h1 class="text-center">Оставьте заявку</h1>
<div class="container text-center">
<div id="form_container">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="form-actions form-group ">
<button type="submit" class="form-control btn btn-success">Отправить</button>
</div>
</form>
</div>
</div>
</body>
</html>
Отправка первого сообщения
Убедитесь, что сервер запущен с помощью команды python manage.py runserver
и откройте http://127.0.0.1:8000/contact
в браузере. Заполните форму и нажмите кнопку Отправить
.
Программа перенаправит на страницу http://127.0.0.1:8000/success
, если сообщение отправилось.
А в консоли должно отобразиться, что сообщение отправилось:
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: =?utf-8?b?0J/RgNC40LLQtdGC?=
From: admin@mysite.com
To: manager@mysite.com
Date: Sat, 03 Oct 2020 11:10:29 -0000
Message-ID: <160172342967.9128.15896163902795968694@DESKTOP-4G7VN>
Email-сервис
Для реальной отправки сообщений нужно настроить сервис: SendGrid, mailgun или SES. К счастью, в Django их очень легко использовать.
Для использования SendGrid нужно создать бесплатный аккаунт и выбрать вариант SMTP. Его легче настраивать при работе с Web API.
Необходимо выполнить верификацию отправителя. Инструкции доступны по этой ссылке. Если раньше можно было отправлять сообщения с бесплатных адресов (gmail.com или yahoo.com), но теперь это не будет работать из-за протокола email-аутентификации DMARC. Поэтому для реальной отправки сообщений нужно почту на своем домене, владение которой придется подтвердить.
После добавления отправителя на странице https://app.sendgrid.com/settings/sender_auth/senders/new, подтвердите почту и переходите к настройке Web API https://app.sendgrid.com/guide/integrate/langs/python.
Следующее окно требует указать название для API-ключа. После этого нужно нажать на Create Key
.
Следуйте инструкциям. На момент написания нужно установить библиотеку sendgrid
и отправить тестовое письмо. Можете воспользоваться этим файлом sg_verify.py. Пройдя все этапы вы увидите сообщение об успешном подключении:
Дальше обновим файл settings.py
, поменяв значение console
на smtp
в переменной EMAIL_BACKEND
. Также добавим еще несколько полей. А также EMAIL_HOST_PASSWORD
с ключем аккаунта SendGrid.
# config/settings.py
# почты для получения писем
RECIPIENTS_EMAIL = ['manager@mysite.com']
# почта отправителя по умолчанию, та что верифицирована
DEFAULT_FROM_EMAIL = 'admin@myiyte.com'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
# ваш уникальный апи-ключ с сайта sendgrid
EMAIL_HOST_PASSWORD = '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'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Вернемся на http://127.0.0.1:8000/contact/, заполним и отправим форму еще раз. Работает!
Выводы
После всех этих этапов у вас будет рабочее приложение с функцией отправки реальных сообщений из Django. Часто это нужно при регистрации пользователей, сбросе пароля, быстрых ответов и так далее.