Read the documentation

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.