Добавление капчи в проект на джанго
В статье будет рассмотрено добавление капчи на основе пакета django-simple-captcha. Установим пакет
pip install django-simple-captcha
В settings.py
INSTALLED_APPS = [
...
'captcha',
...
]
Далее, по документации нам нужно выполнить миграцию:
python manage.py migrate
Затем, в корневой список маршрутов добавим строчку:
urlpatterns = [
...
path('captcha/', include('captcha.urls')),
...
]
Проверять будем на странице с обратной связью. Вот такая форма. Здесь поля name
и email
отключены для зарегистрированных пользователей и заполняются из профиля, и используются поля
name_hidden
и email_hidden
, т.к. при отправке на сервер отключенные поля не передаются.
class ContactForm(forms.Form):
name = forms.CharField(
label='Имя',
widget=forms.TextInput(attrs={'class': 'form-input'})
)
email = forms.CharField(
required=False,
label='E-mail',
widget=forms.TextInput(attrs={'class': 'form-input'})
)
content = forms.CharField(
label="Сообщение",
widget=forms.Textarea(attrs={'rows': 3}),
max_length=3000
)
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(ContactForm, self).__init__(*args, **kwargs)
if user and user.is_authenticated:
self.fields['name'].initial = user.username
self.fields['name'].widget.attrs['disabled'] = True # Отключаем поле
self.fields['name'].required = False
self.fields['email'].initial = user.email
self.fields['email'].widget.attrs['disabled'] = True # Отключаем поле
self.fields['email'].required = False
# Добавляем скрытые поля для передачи данных на сервер
self.fields['name_hidden'] = forms.CharField(
initial=user.username,
widget=forms.HiddenInput()
)
self.fields['email_hidden'] = forms.EmailField(
initial=user.email,
widget=forms.HiddenInput()
)
И представление формы.
class ContactView(DataMixin, FormView):
form_class = ContactForm
success_url = reverse_lazy('home')
template_name = "notes/contact.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['page_description'] = 'Обратная связь'
context['page_description_name'] = 'description'
return self.get_mixin_context(context, title_page='Обратная связь')
def form_valid(self, form):
# Если пользователь аутентифицирован, используем данные из скрытых полей
if self.request.user.is_authenticated:
name = form.cleaned_data['name_hidden']
email = form.cleaned_data['email_hidden']
else:
# Получаем данные из формы
name = form.cleaned_data['name']
email = form.cleaned_data['email']
content = form.cleaned_data['content']
# Формируем тему и текст письма
subject = f"Новое сообщение от {name}"
message = f"""
Имя: {name}
Email: {email}
Сообщение:
{content}
"""
# Отправляем письмо
try:
send_mail(
subject, # Тема письма
message, # Текст письма
settings.DEFAULT_FROM_EMAIL, # От кого (ваш email из настроек)
[settings.EMAIL_ADMIN], # Кому (ваш email из настроек)
fail_silently=False, # Выводить ошибки, если отправка не удалась
)
# Добавляем сообщение об успехе
messages.success(self.request, 'Ваше сообщение успешно отправлено!')
except Exception as e:
# Добавляем сообщение об ошибке
messages.error(self.request, f'Ошибка при отправке письма: {e}')
return super().form_valid(form)
def form_invalid(self, form):
# Восстанавливаем значения полей name и email из скрытых полей
if self.request.user.is_authenticated:
form.data = form.data.copy() # Делаем копию данных формы
form.data['name'] = form.data.get('name_hidden', '')
form.data['email'] = form.data.get('email_hidden', '')
return super().form_invalid(form)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
И шаблон
{% block content %}
<div class="article">
<h2> {{ page_description }}</h2>
<form method="post">
{% csrf_token %}
<div class="form-error">{{ form.non_field_errors }}</div>
{% for field in form %}
{% if not field.is_hidden %} <!-- Проверяем, не является ли поле скрытым -->
<div class="form-field">
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label> {{ field }}
<div class="form-error">{{ field.errors }}</div>
</div>
{% else %}
<div class="hidden-field">{{ field }}</div>
{% endif %}
{% endfor %}
<button type="submit">Отправить</button>
</form>
</div>
{% endblock %}
Вот пожалуй и всё.
Категория: Программирование | автор: root
Опубликовано: 13-02-2025 17:13 | Обновлено: 25-02-2025 10:47