Adding reCAPTCHA to Django Forms

Posted on Feb 14, 2021

Register Your Application

Go to the reCAPTCHA admin and register your application.

  1. Select reCAPTCHA v2
  2. Add your domain, e.g. google.com

Add Django reCAPTCHA Package

pip install django-recaptcha

  • depending on how you are managing packages you may need to update your requirements.txt file, or use pipenv install djanto-recaptcha instead.
  • You can find out more about the package here.

Update Settings

  1. Add captcha to the INSTALLED_APPS in settings.py
    # mysite/settings.py
    INSTALLED_APPS = [
    	 ...,
    	 'captcha',
    	 ...
    ]
    
  2. Prevent reCAPTCHA throwing an error when running locally and during automated tests and set the reCAPTCHA keys from environment variables when running in production.
    # mysite/settings.py
    if debug == True:
        SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"]
    else:
        RECAPTCHA_PUBLIC_KEY = os.getenv("RECAPTCHA_PUBLIC_KEY")
        RECAPTCHA_PRIVATE_KEY = os.getenv("RECAPTCHA_PRIVATE_KEY")
    
    • Environment variables are used to avoid committing secrets to your git repository and enable you to easily run the application on different domains.

Add reCAPTCHA to a Form

  1. Import the ReCaptchaField from captcha.fields
  2. Add a field called captcha of type ReCaptchaField to your form fields.
# mysite/my-app/forms.py
from django import forms
from captcha.fiels import ReCaptchaField

class MyForm(forms.Form):
	captcha = ReCaptchaField
	...

Testing the Form

If your settings are configured correctly your test will run with reCAPTCHA in test mode, so it will automatically approve all submissions without making a call to Google, but only as long as a value is passed to the g-recaptcha-response field. For example:

form_data = {
	 ...,
	 "g-recaptcha-respones": "dummy",
	 ...
}

If you want to do a full test while developing locally you can also create a reCAPTCHA for 127.0.0.1, or localhost, or both domains. You can then use the values produced as the defaults in the settings.py file, so your app calls google when it is running locally.

# mysite/settings.py
import sys
...
if "test" in sys.argv:
    SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"]
else:
    RECAPTCHA_PUBLIC_KEY = os.getenv("RECAPTCHA_PUBLIC_KEY", "your-test-recaptcha-key")
    RECAPTCHA_PRIVATE_KEY = os.getenv("RECAPTCHA_PRIVATE_KEY", "your-test-recaptcha-secret")