Капча в форму на Django: пошаговая настройка с нуля
Форму на Django заваливают спам-ботами. Разбираем с нуля, как подключить проверку через reCAPTCHA v2 и hCaptcha, чтобы бот не отправил форму, а живой человек не заметил защиты.

Форма обратной связи на Django без защиты в первый же месяц собирает десятки автоматических отправок: реклама, ссылки, бессмысленный текст. Дальше — либо ручная чистка почты, либо капча. За 20–30 минут вы подключите к форме проверку через Google reCAPTCHA v2 (галочка «Я не робот») и увидите, как форма перестаёт принимать отправки без пройденной проверки. Пример собран на Django 5.x, но так же работает на Django 4.2 LTS.
Что нужно иметь до начала
- Рабочий проект Django 4.2+ или 5.x с хотя бы одной формой на базе
forms.Formилиforms.ModelForm. - Python 3.10+ и доступ к терминалу проекта, где активировано виртуальное окружение.
- Аккаунт Google для регистрации ключей reCAPTCHA. Регистрация ключей бесплатна.
- Доступ к файлу
settings.pyи к шаблону, где выводится форма.
Проверять капчу мы будем через готовый пакет django-recaptcha — он инкапсулирует запрос к серверу Google и не заставляет писать проверку токена руками. Пакет живой и обновляется; актуальную версию и совместимость смотрите на его странице в PyPI.
Шаг 1. Получите ключи reCAPTCHA
- Откройте консоль reCAPTCHA и нажмите на создание нового сайта.
- Выберите тип reCAPTCHA v2 → «Флажок "Я не робот"». Именно v2 даёт видимую галочку, которую проще всего встроить в обычную форму.
- В поле доменов добавьте свой домен. Для локальной разработки добавьте
localhostи127.0.0.1— без них капча на локальной машине выдаст ошибку домена. - После сохранения вы получите два ключа: Site key (публичный, уходит в HTML) и Secret key (приватный, остаётся на сервере).
Проверка: на странице ключей вы видите два длинных значения. Оба понадобятся на следующем шаге. Secret key никому не показывайте и не кладите в git.
Тестовые ключи для отладки
Google публикует пару тестовых ключей, которые всегда проходят проверку без реального взаимодействия — их адрес есть в официальном FAQ reCAPTCHA. Они удобны, пока вы проверяете, что форма вообще принимает поле капчи. На боевой сайт тестовые ключи ставить нельзя: они не защищают ни от кого.
Шаг 2. Установите пакет
# в активированном виртуальном окружении
pip install django-recaptcha
Проверка: команда pip show django-recaptcha выводит установленную версию. Запишите её — при обновлении Django имя пакета или путь импорта может измениться, и версия поможет свериться с документацией.
Шаг 3. Пропишите настройки
Добавьте приложение в INSTALLED_APPS и вынесите ключи в переменные окружения, а не в код.
# settings.py
import os
INSTALLED_APPS = [
# ... остальные приложения
"django_recaptcha",
]
# Ключи читаем из окружения, чтобы secret не попал в репозиторий
RECAPTCHA_PUBLIC_KEY = os.environ.get("RECAPTCHA_PUBLIC_KEY", "")
RECAPTCHA_PRIVATE_KEY = os.environ.get("RECAPTCHA_PRIVATE_KEY", "")
Имя пакета для импорта — django_recaptcha (с подчёркиванием). В старых версиях приложение называлось иначе; если у вас установлена не самая свежая сборка, точное имя приложения и поля смотрите в README вашей версии.
Проверка: команда python manage.py check проходит без ошибок про неизвестное приложение.
Ключ Site key публичный по своей природе — он всё равно уйдёт в HTML-страницу. А вот Secret key утекший в открытый репозиторий позволяет обойти вашу защиту. Разделение этих двух ключей — не формальность, а весь смысл схемы.
Шаг 4. Добавьте поле в форму
Пакет даёт готовое поле формы и виджет. Добавьте его в вашу форму как обычное поле.
# forms.py
from django import forms
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Checkbox
class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label="Имя")
email = forms.EmailField(label="E-mail")
message = forms.CharField(widget=forms.Textarea, label="Сообщение")
# Поле капчи. Виджет с галочкой "Я не робот"
captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox())
Валидацию токена пакет делает сам внутри метода очистки поля: если галочка не пройдена или токен просрочен, форма получает ошибку валидации по этому полю. Никакого ручного запроса к серверу Google писать не нужно.
Проверка: при запуске сервера и открытии формы в браузере под полями появляется блок reCAPTCHA с флажком.
Шаг 5. Выведите форму в шаблоне
Виджет капчи сам подтягивает нужный JavaScript, отдельно скрипт Google подключать не надо. Достаточно вывести форму.
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Отправить</button>
</form>
Проверка: в исходном коде страницы (Ctrl+U) виден блок с классом g-recaptcha и подключённый скрипт reCAPTCHA.
Шаг 6. Проверьте обработку во view
Во view ничего специфичного для капчи не нужно — обычная проверка form.is_valid(). Если галочка не пройдена, метод вернёт False.
# views.py
from django.shortcuts import render, redirect
from .forms import FeedbackForm
def feedback(request):
if request.method == "POST":
form = FeedbackForm(request.POST)
if form.is_valid():
# капча уже проверена внутри is_valid()
# тут сохраняем или отправляем письмо
return redirect("feedback_done")
else:
form = FeedbackForm()
return render(request, "feedback.html", {"form": form})
Проверка: отправьте форму, не трогая галочку — под полем капчи появится ошибка валидации, данные не сохранятся. Пройдите галочку и отправьте снова — форма примет отправку.
Если не получилось
- «ERROR for site owner: Invalid domain for site key» — домен, с которого открыта форма, не добавлен в список доменов ключа. Для локальной работы добавьте
localhostи127.0.0.1в настройках ключа в консоли reCAPTCHA. - Форма всегда невалидна, ошибка на поле captcha, хотя галочка пройдена — чаще всего перепутаны местами public и private ключи или один из них пустой. Проверьте, что переменные окружения реально прочитаны: временно выведите первые символы ключа в лог.
- ModuleNotFoundError: No module named 'django_recaptcha' — пакет установлен в другое окружение либо приложение не добавлено в
INSTALLED_APPS. Проверьтеpip show django-recaptchaв том же окружении, где запускается сервер. - Блок капчи не отображается — часто мешает Content Security Policy: браузер блокирует загрузку скрипта Google. В консоли разработчика будет запись о заблокированном ресурсе. Разрешите домены reCAPTCHA в вашей CSP.
- Ошибка про истёкший токен при медленной отправке — токен reCAPTCHA живёт ограниченное время (порядка нескольких минут). Если пользователь долго заполнял форму, галочку нужно пройти заново.
reCAPTCHA или hCaptcha
Если reCAPTCHA не подходит по причинам приватности или доступности сервисов Google, тот же пакет и похожая схема работают с hCaptcha и с reCAPTCHA v3 (невидимая, по оценке риска). Отличия для новичка сводятся к следующему:
| Вариант | Что видит пользователь | Особенность |
|---|---|---|
| reCAPTCHA v2 (флажок) | Галочка «Я не робот», иногда картинки | Простое подключение, понятный результат: прошёл/не прошёл |
| reCAPTCHA v3 | Ничего, работает в фоне | Возвращает оценку риска — нужно самому решать порог отсечения |
| hCaptcha | Аналог галочки/картинок | Отдельная регистрация ключей, свой провайдер |
Для первой формы берите v2 с флажком: результат бинарный, отлаживать нечего. v3 требует продумать логику порога и что делать с пограничными оценками — это отдельная тема, здесь её не разворачиваем.
Что делать дальше
Капча закрывает форму от простых ботов, но не заменяет остальную гигиену. После подключения стоит настроить ещё три вещи:
- Вынести оба ключа в переменные окружения или в
.envи убедиться, что secret не попал в git-историю. - Добавить серверную защиту от частых отправок с одного адреса — капча не спасает от медленного ручного спама.
- Проверить форму на боевом домене с настоящими ключами: тестовые ключи Google на проде не защищают.
Если у вас несколько форм, поле капчи можно вынести в общий базовый класс формы, чтобы не дублировать его в каждой.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: django-recaptcha на PyPI, reCAPTCHA v2 — официальная документация Google
Частые вопросы
А если у меня Django 4.2, а не 5.x — инструкция подойдёт?
Капча не отображается вообще, форма без блока «Я не робот». Что смотреть?
Нужно ли отдельно проверять токен капчи во view?
Можно ли использовать капчу без аккаунта Google?
Защитит ли капча от всего спама?
Токен просрочился, пока пользователь заполнял длинную форму. Как быть?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.