django-captcha-kit
The same contact form, protected by six interchangeable providers. Nothing in the
form code changes between them: only CAPTCHA_KIT does.
Providers
None none
Renders a hidden field and accepts everything. For development and tests.
Local Math Captcha math default
A small sum solved locally. No third party, no network call, no cookie.
Local Image Captcha image
Distorted characters drawn locally with Pillow. No third party, no network.
Cloudflare Turnstile turnstile
Privacy-first widget from Cloudflare, usually invisible to the visitor.
Google reCAPTCHA v2 recaptcha
The classic checkbox, verified against Google.
hCaptcha hcaptcha
Independent alternative with the same siteverify protocol.
Switching provider
The demo picks the provider from the URL, but a real project names one in its settings:
CAPTCHA_KIT = {
"DEFAULT": "turnstile",
"PROVIDERS": {
"turnstile": {
"SITE_KEY": env("TURNSTILE_SITE_KEY"),
"SECRET_KEY": env("TURNSTILE_SECRET_KEY"),
},
},
}
Changing DEFAULT is the whole migration. Try it by editing
CAPTCHA_DRIVER in .env, then reload
the form mixin page.