Создание контактной формы в Django и привязываем почту


07 декабря 2020


Создаем форму обратной связи в Djano с почтовым уведомлением

В этой статье разберем создание формы обратной связи в Django, с моделью и вьюшкой, с последующей отправкой уведомлений на указанный почтовый ящик. Для дальнейшей работы подразумевается, что у вас установлен Python и Django.

Первое что нужно сделать - это создать проект. В примере ниже будет создан проект с названием 'project':

python django-admin startproject project

Перейдя в папку проекта создадим приложение 'contact_form':

cd project
python manage.py startapp contact_form

Что бы это приложение работало его нужно прописать в 'settings.py':

Объявление приложения в settings.py в Django

 

Создание модели

Каждое удачное заполнение формы будет добавлять данные в базу и отправлять их на почту. Что бы это было выполнимо создадим модель со следующим содержимым:

  • 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

Создание модели для формы обратной связи в Django

Таблица в базе данных будет создана после выполнения миграций:

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')
]

Объявление URL для формы обратной связи в Django urls.py

Что бы данные с заполненных форм не только отправлялись на почту, но и отображались в панели администрирования - создадим соответствующую запись в файле admin.py:

from django.contrib import admin
from .models import Contact


@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
    pass

Регистрация модели Django в admin.py

 

Подключение почты

Для возможности отправки писем в 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

Настройка отправки писем в Django settings.py

Для отправки сообщения мы можем использовать функцию 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': 'Напишите тут ваше сообщение'
                }
            )
        }

Создание формы обратной связи в Django

Создание формы подразумевает и возможность вывода ее в шаблоне (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>

Вызов формы с шаблона HTML в Django

{{ form }} выводит все окна формы в одну строку. Мы можем написать {{ form.as_p }} для вывода каждого окна в отдельном параграфе (</p>). Кроме параграфа можно выводить в:

  • form.as_table - в виде таблицы;
  • form.as_ul - в виде маркированного списка.

 

Тестирование формы

После этого можно запустить сервер и проверить работу формы:

python manage.py runserver

Запуск отладочного сервера Django

При успешной отправки формы у нас появятся следующие сообщения:

Запуск и тестирование формы в Django

В панели администрирование, если зайти по адресу '/admin/', эти сообщения так же можно увидеть:

Просмотр модели в панели администрирования Django

Для входа в панель администрирования может понадобится создать пользователя через следующую команду:

python django-admin createsuperuser

 

...

Теги: #python #django


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.