Django reCAPTCHA
django-recaptcha is a Django application that integrates Google reCAPTCHA functionality into Django forms. It provides form fields and widgets for reCAPTCHA v2 (Checkbox, Invisible) and reCAPTCHA v3. The current version is 4.1.0, and the project is actively maintained with regular releases to support the latest Django and Python versions.
Warnings
- breaking In version 4.0.0, the internal package namespace was renamed from `captcha` to `django_recaptcha` to avoid conflicts. All import statements for `ReCaptchaField`, `ReCaptchaWidget`, and other components must be updated.
- breaking Version 3.0.0 introduced support for Django 3.2 and 4.0, removing the upper Django dependency constraint. This means older Django versions (prior to 3.2) are no longer officially supported by this major release.
- gotcha For production environments, you must set `RECAPTCHA_PUBLIC_KEY` and `RECAPTCHA_PRIVATE_KEY` in your Django settings. If these are not provided, the library defaults to Google's test keys, which always validate successfully but display a warning and only work for reCAPTCHA v2. This can lead to unverified submissions in production.
- gotcha When using reCAPTCHA v3, the validation relies on a score returned by Google. By default, `django-recaptcha` will not automatically fail a form submission based on this score unless you configure `RECAPTCHA_SCORE_THRESHOLD` in your settings or explicitly check `form.cleaned_data['recaptcha'].get('score')` in your view. If not configured, all successful token responses pass, regardless of the score.
- gotcha In versions prior to 4.0.0, reCAPTCHA v3 tokens were requested on page load. If a user left the form open for more than two minutes before submitting, the token would expire, causing validation to fail. This issue was addressed in version 4.0.0.
Install
-
pip install django-recaptcha
Imports
- ReCaptchaField
from django_recaptcha.fields import ReCaptchaField
- ReCaptchaV2Checkbox
from django_recaptcha.widgets import ReCaptchaV2Checkbox
- ReCaptchaV3
from django_recaptcha.widgets import ReCaptchaV3
Quickstart
# settings.py
import os
INSTALLED_APPS = [
# ... other apps
'django_recaptcha',
]
RECAPTCHA_PUBLIC_KEY = os.environ.get('RECAPTCHA_PUBLIC_KEY', '')
RECAPTCHA_PRIVATE_KEY = os.environ.get('RECAPTCHA_PRIVATE_KEY', '')
# Optional: For reCAPTCHA v3, set a default score threshold
# RECAPTCHA_SCORE_THRESHOLD = 0.5
# forms.py
from django import forms
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Checkbox # or ReCaptchaV3
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox) # Default to V2 Checkbox
# views.py
from django.shortcuts import render, redirect
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Process the form data
# For ReCaptchaV3, you might check form.cleaned_data['recaptcha'].get('score')
return redirect('success_url') # Replace with your success URL name
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
# templates/contact.html
<!-- Make sure to load the Google reCAPTCHA API script in your base template or head, e.g., -->
<!-- <script src="https://www.google.com/recaptcha/api.js" async defer></script> -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>