В этой статье разберем создание формы обратной связи в Django, с моделью и вьюшкой, с последующей отправкой уведомлений на указанный почтовый ящик. Для дальнейшей работы подразумевается, что у вас установлен Python и Django.
Первое что нужно сделать - это создать проект. В примере ниже будет создан проект с названием 'project':
python django-admin startproject project
Перейдя в папку проекта создадим приложение 'contact_form':
cd project
python manage.py startapp contact_form
Что бы это приложение работало его нужно прописать в 'settings.py':
Создание модели
Каждое удачное заполнение формы будет добавлять данные в базу и отправлять их на почту. Что бы это было выполнимо создадим модель со следующим содержимым:
- first_name - имя отправителя;
- last_name - фамилия отправителя;
- email - почта для обратной связи;
- message - в этом поле можно будет описать суть обращения.
Эти поля определяются в файле models.py, благодаря которым будет создана таблица в базе данных. Обратите внимание на возможную длину ('max_length'), так как вы можете захотеть увеличить эти значения:
from django.db import models
class Contact(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.EmailField(max_length=200)
message = models.TextField(max_length=1000)
def __str__(self):
# Будет отображаться следующее поле в панели администрирования
return self.email
Таблица в базе данных будет создана после выполнения миграций:
python manage.py makemigrations
python manage.py migrate
Создание url и регистрация модели в панели администрирования
В описываемом примере будет создано 2 дополнительных URL. По первому адресу будет открываться форма, а второй url будет возвращать ответ в случае успешного заполнения. Каждая из ссылок ассоциируется с классом или функцией, которые будут созданы далее. Эти URL я прописал в файле urls.py проекта:
from django.contrib import admin
from django.urls import path
from contact_form.views import ContactForm, success
urlpatterns = [
path('admin/', admin.site.urls),
path('', ContactCreate.as_view(), name='contact_page'),
path('success/', success, name='success_page')
]
Что бы данные с заполненных форм не только отправлялись на почту, но и отображались в панели администрирования - создадим соответствующую запись в файле admin.py:
from django.contrib import admin
from .models import Contact
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
pass
Создание первого приложения во фреймворке Python Django 3
Подключение почты
Для возможности отправки писем в Django уже реализован SMTP агент. Что бы мы могли его использовать нам нужно определить значение следующих переменных в файле setting.py:
- EMAIL_HOST - домен отправителя, например smtp.gmail.com;
- EMAIL_PORT - порт SMTP, например 587;
- EMAIL_HOST_USER - имя пользователя, например admin@gmail.com;
- EMAIL_HOST_PASSWORD - пароль;
- EMAIL_USE_TLS - используется ли шифрование (для всех публичных доменов, типа gmail - да).
Большая часть настроек подключения можно найти у почтовых провайдеров. Для gmail и yandex, например, вы еще должны будете включить разрешение на отправку писем в настройках почтового ящика и доступ с небезопасных агентов.
Ниже пример настроенного подключения для gmail.com:
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'user@gmail.com'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_USE_TLS = True
Для отправки сообщения мы можем использовать функцию send_mail() из django.core.mail где можно определить:
- subject - тема сообщения;
- message - содержание;
- from_email - от кого отправляем письмо (в нашем случае будет использоваться один и тот же);
- recipient_list - список получателей;
Можно заполнить и опциональные поля:
- auth_user и auth_password - используется в случае, если вы будете использовать разные ящики;
- connection - другие настройки для оправки писем;
- html_message - если вы планируете отправлять сообщение в разметке HTML.
В зависимости от того было ли сообщение успешно доставлено вернется 0 или 1:
from django.core.mail import send_mail
send_mail('Тема сообщения',
'Содержание',
'test@gmail.com',
['получатель1@gmail.com', 'получатель2@gmail.com']
)
Создание формы с ModelForm
В Django формы можно разделить на те, которые создаются на основе созданной модели (ModelForm) либо те где мы должны определять поля сами (Form). Основной плюс в использовании форм-моделей в том, что нам не нужно будет определять требования к полям (длина строки, наличие знака @ в адресе пользователя и т.д.) - это будет сделано автоматически на основе того что мы указали в самой модели. Для определения форм, обычно, создается файл forms.py в папке с приложением. В этот файл нужно поместить следующую информацию:
from django.forms import ModelForm
from django.forms import Textarea
from .models import Contact
class ContactForm(ModelForm):
class Meta:
# Определяем модель, на основе которой создаем форму
model = Contact
# Поля, которые будем использовать для заполнения
fields = ['first_name', 'last_name', 'email', 'message']
widgets = {
'message': Textarea(
attrs={
'placeholder': 'Напишите тут ваше сообщение'
}
)
}
Создание формы подразумевает и возможность вывода ее в шаблоне (HTML). Для корректного вывода формы может понадобится определение стилей в виде классов или других CSS свойств. На примере выше добавлено свойство placeholder, которое будет выводить подсказку в этом окне.
В принципе форму не обязательно создавать отдельно, если вы не планируете использовать дополнительные стили. Такую же форму можно создать и с помощью класса CreateView.
Создание представление с CreateView
В файле views.py мы можем импортировать класс CreateView, на основе которого определим:
- model - название модели, на основе которой создадим форму и в которую будет добавляться новые данные;
- fields - поля, которые будем использовать;
- success_url - источник, куда будет выполнено перенаправление в случае успешной валидации полей формы. В случае ниже пользователю вернется результат функции 'success'.
Опционально можно использовать:
- form_class - название класса формы, которую мы создавали выше. Если это поле не заполнено создастся обычная форма основанная на модели. При этом должна быть определена переменная fields либо form_class. Если у вас будут обе переменных появится ошибка 'Specifying both 'fields' and 'form_class' is not permitted.'.
from django.views.generic import CreateView
from .models import Contact
from django.urls import reverse_lazy
from django.http import HttpResponse
from django.core.mail import send_mail
from .forms import ContactForm
class ContactCreate(CreateView):
model = Contact
# fields = ["first_name", "last_name", "message"]
success_url = reverse_lazy('success_page')
form_class = ContactForm
def form_valid(self, form):
# Формируем сообщение для отправки
data = form.data
subject = f'Сообщение с формы от {data["first_name"]} {data["last_name"]} Почта отправителя: {data["email"]}'
email(subject, data['message'])
return super().form_valid(form)
# Функция отправки сообщения
def email(subject, content):
send_mail(subject,
content,
'отправитель@gmail.com',
['получатель1@gmail.com']
)
# Функция, которая вернет сообщение в случае успешного заполнения формы
def success(request):
return HttpResponse('Письмо отправлено!')
Последний момент - мы должны создать шаблон для отображения формы. CretateView принимает 'POST' запросы, а это значит что мы должны защитить их с помощью csrf_token. CreateView, так же как и другие представления, могут использовать шаблон указанный в переменной 'template_name'. Если эта переменная не определена, в случае выше, будет искаться файл 'contact_form.html' (зависит от названия класса). Саму форму можно вызвать использовав переменную {{ form }}.
Содержимое файла и его путь можно посмотреть на следующем скриншоте:
<form method="POST">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
{{ form }} выводит все окна формы в одну строку. Мы можем написать {{ form.as_p }} для вывода каждого окна в отдельном параграфе (</p>). Кроме параграфа можно выводить в:
- form.as_table - в виде таблицы;
- form.as_ul - в виде маркированного списка.
Тестирование формы
После этого можно запустить сервер и проверить работу формы:
python manage.py runserver
При успешной отправки формы у нас появятся следующие сообщения:
В панели администрирование, если зайти по адресу '/admin/', эти сообщения так же можно увидеть:
Для входа в панель администрирования может понадобится создать пользователя через следующую команду:
python django-admin createsuperuser
...