Блог
  • Начало
  • Обо мне
  • Обратная связь

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

Дата и время: 18 октября 2014 г. 22:27 | Категория: Веб-разработка, Django

Практически на любом сайте требуется форма обратной связи, и в данном посте я опишу простейшие шаги её создания.


1. Создание модели формы

Для начала необходимо описать модель нашей формы (можно в views.py или другом файле).

from django import forms

class ContactForm(forms.Form):
	subject = forms.CharField(max_length = 100)
	sender = forms.EmailField()
	message = forms.CharField()
	copy = forms.BooleanField(required = False)

Модель формы представляет собой обычный класс, унаследованный от класса Form. Свойства класса имеют следующий смысл:
- subject: тема сообщения (символьное поле, ограниченное 100 символами);
- sender: e-mail отправителя (специальное поле для e-mail, включающее все необходимые проверки);
- message: текст сообщения (неограниченное текстовое поле);
- copy: флаг, который пользователь устанавливает, если хочет получить копию сообщения себе на e-mail (булевая переменная, представляющая собой необязательный к заполнению чекбокс).


2. Создание представления

Теперь нам необходимо передать данную форму в какое-либо представление и обработать данные, заполненные пользователем.

from django.shortcuts import render
from django.http import HttpResponse
from django.core.mail import send_mail, BadHeaderError

def contactView(request):
	if request.method == 'POST':
		form = ContactForm(request.POST)
		#Если форма заполнена корректно, сохраняем все введённые пользователем значения
		if form.is_valid():
			subject = form.cleaned_data['subject']
			sender = form.cleaned_data['sender']
			message = form.cleaned_data['message']
			copy = form.cleaned_data['copy']

			recipients = ['ВАШ_EMAIL_ДЛЯ_ПОЛУЧЕНИЯ_СООБЩЕНИЯ']
			#Если пользователь захотел получить копию себе, добавляем его в список получателей
			if copy:
				recipients.append(sender)
			try:
				send_mail(subject, message, 'ВАШ_EMAIL_ДЛЯ_ОТПРАВКИ_СООБЩЕНИЯ', recipients)
			except BadHeaderError: #Защита от уязвимости
				return HttpResponse('Invalid header found')
			#Переходим на другую страницу, если сообщение отправлено
			return render(request, 'site/thanks.html')
	else:
		#Заполняем форму
		form = ContactForm()
	#Отправляем форму на страницу
	return render(request, 'site/contact.html', {'form': form})

В документации в качестве третьего параметра метода send_mail предлагается отправлять строку, находящуюся в переменной sender, но у меня данный фокус не прошёл.


3. Конфигурирование settings.py

В settings.py необходимо указать следующие переменные:

EMAIL_USE_TLS = True
EMAIL_HOST = 'ХОСТ_ВАШЕГО_ПОЧТОВОГО_SMTP_СЕРВЕРА' #Например, smtp.gmail.com
EMAIL_HOST_USER = 'ВАШ_ЛОГИН_НА_СЕРВЕРЕ' #Например, user@gmail.com. Именно его необходимо указывать как ВАШ_EMAIL_ДЛЯ_ОТПРАВКИ_СООБЩЕНИЯ в исходном коде предыдущего пункта
EMAIL_HOST_PASSWORD = 'ВАШ_ПАРОЛЬ_НА_СЕРВЕРЕ'


4. Добавление разметки в шаблон

На заключительном этапе осталось добавить необходимую разметку в шаблон.

<form action="/contact/" method="post">{% csrf_token %}
    {{ form.non_field_errors }}
	<div>
	  <label for="id_subject">Тема:</label>
	  {{ form.subject.errors }}
	  {{ form.subject }}
	</div>
	<div>
	  <label for="id_sender">E-mail:</label>
	  {{ form.sender.errors }}
	  {{ form.sender }}
	</div>
	<div>
	  <label for="id_message">Сообщение:</label>
	  {{ form.message.errors }}
	  {{ form.message }}
	</div>
	<div>
	  {{ form.copy.errors }}
	  <label for="id_copy">Отправить копию себе {{ form.copy }}</label>
	</div>
	<input type="submit" value="Отправить"/>
</form>

{% csrf_token %} необходим для исключения некоторых уязвимостей. Обратите внимание, что id лейблов по умолчанию должны быть id_имя_свойства.


5. Заключение

На текущий момент получена работоспособная форма, но хотелось бы изменить дизайн элементов формы Django, а в случае с полем message, изменить элемент на textarea. Это достигается следующим образом:

...
class ContactForm(forms.Form):
	...
	message = forms.CharField(widget = forms.Textarea(attrs = {'class': 'form-control'}))
	...

Полный список виджетов можно найти в документации. Атрибуты виджета (в том числе CSS классы) указываются в параметре attrs при его создании.

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

comments powered by Disqus
Select language:
  • Русский
  • English

  • Программирование

    Python C++ JavaScript

    Веб-разработка

    Django ASP.NET

    Мобильная разработка

    Windows Phone Android

    Разработка игр

    Unity3d Blender

    Артем Устимов © 2014