{"id":23632,"library":"drf-recaptcha","title":"DRF reCAPTCHA","description":"A Django REST Framework field and serializer for Google reCAPTCHA (v2 and v3) verification. Current version 4.0.3 supports Django ≥4.2, Python ≥3.10, DRF ≥3.14. Released irregularly; latest updates add Django 5.2 and Python 3.13 support.","status":"active","version":"4.0.3","language":"python","source_language":"en","source_url":"https://github.com/llybin/drf-recaptcha","tags":["django","django-rest-framework","recaptcha","serializer","captcha"],"install":[{"cmd":"pip install drf-recaptcha","lang":"bash","label":"PyPI install"}],"dependencies":[{"reason":"Core dependency for web framework","package":"django","optional":false},{"reason":"Required for serializer field integration","package":"djangorestframework","optional":false},{"reason":"Used to verify reCAPTCHA with Google's API","package":"requests","optional":false}],"imports":[{"note":"Import from the serializers submodule, not top-level package","wrong":"from drf_recaptcha import ReCaptchaSerializer","symbol":"ReCaptchaSerializer","correct":"from drf_recaptcha.serializers import ReCaptchaSerializer"},{"note":"Field class is in the fields submodule","wrong":"from drf_recaptcha import ReCaptchaField","symbol":"ReCaptchaField","correct":"from drf_recaptcha.fields import ReCaptchaField"}],"quickstart":{"code":"import os\nfrom django.conf import settings\nfrom rest_framework import serializers\nfrom drf_recaptcha.serializers import ReCaptchaSerializer\n\nsettings.configure(\n    DRF_RECAPTCHA_SECRET_KEY=os.environ.get('RECAPTCHA_SECRET_KEY', 'test-secret'),\n    INSTALLED_APPS=['django.contrib.contenttypes', 'django.contrib.auth'],\n    DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n)\nimport django\ndjango.setup()\n\nclass MySerializer(ReCaptchaSerializer):\n    email = serializers.EmailField()\n\n# Dummy data for testing (use valid reCAPTCHA response in production)\ndata = {'email': 'test@example.com', 'recaptcha': 'dummy-response'}\nserializer = MySerializer(data=data)\nprint(serializer.is_valid())","lang":"python","description":"Quickstart: define a serializer inheriting ReCaptchaSerializer. Configure DRF_RECAPTCHA_SECRET_KEY in Django settings. For testing, set DRF_RECAPTCHA_TESTING=True to bypass verification."},"warnings":[{"fix":"Ensure Django ≥4.2, Python ≥3.10, DRF ≥3.14 before upgrading to drf-recaptcha ≥4.0.","message":"Version 4.0.0 drops support for Django 3.2, 4.0, 4.1; Python 3.8, 3.9; and DRF 3.11, 3.12, 3.13. Upgrade your environment if migrating from <4.0.","severity":"breaking","affected_versions":"<4.0"},{"fix":"Add `Meta.exclude = ['recaptcha']` or use `fields` to limit output fields.","message":"The `ReCaptchaSerializer` includes a `recaptcha` field by default but does not hide it from the serializer output. This field will be serialized back to the client unless explicitly excluded using `exclude` or `fields`.","severity":"gotcha","affected_versions":"All"},{"fix":"Upgrade to ≥3.2.0 if you need a required score of 0. Now a score of 0 correctly allows all traffic.","message":"In reCAPTCHA v3, the default required score is 0.5. Setting the required score to 0 (to allow all) was broken before version 3.2.0; the score 0 was treated as None and overridden to 0.5.","severity":"gotcha","affected_versions":"<3.2.0"},{"fix":"Use `DRF_RECAPTCHA_TESTING=True` only in test environments; for real bypass consider using a mock serializer.","message":"The setting `DRF_RECAPTCHA_TESTING` when set to `True` skips actual verification. However, the field will still require a non-empty string. This is intended for testing but may confuse users expecting full bypass.","severity":"deprecated","affected_versions":"All"},{"fix":"Always pass the intended secret key explicitly when using multiple keys: `ReCaptchaField(secret_key='...')`.","message":"Multiple/ dynamic secret keys (introduced in 3.0.0) require passing a secret key via the serializer's `context` or field kwargs. If not provided, the default `DRF_RECAPTCHA_SECRET_KEY` is used. Forgetting this can lead to wrong key usage.","severity":"gotcha","affected_versions":"≥3.0.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Use `from drf_recaptcha.serializers import ReCaptchaSerializer`.","cause":"Importing from top-level package instead of submodule.","error":"AttributeError: module 'drf_recaptcha' has no attribute 'ReCaptchaSerializer'"},{"fix":"Ensure `DRF_RECAPTCHA_SECRET_KEY` is set in Django settings (e.g., `os.environ.get('RECAPTCHA_SECRET_KEY')`). For quick tests, configure settings before using the serializer.","cause":"Missing Django settings configuration or missing env variable.","error":"django.core.exceptions.ImproperlyConfigured: Requested setting DRF_RECAPTCHA_SECRET_KEY, but settings are not configured."},{"fix":"Include the 'g-recaptcha-response' token from the client in your request data under the key `recaptcha`.","cause":"The `recaptcha` field is required by default and missing from request data.","error":"ValidationError: ['This field is required.'] on recaptcha field"},{"fix":"Use `ReCaptchaV3Field` for score-based verification, or remove the `score` argument from `ReCaptchaV2Field`.","cause":"The `ReCaptchaV2Field` does not accept a `score` argument (only v3 fields do).","error":"TypeError: __init__() got an unexpected keyword argument 'score'"},{"fix":"Set `version='v2'` or `version='v3'` (string). Default is 'v2'.","cause":"A wrong value passed to the `version` parameter of `ReCaptchaField`.","error":"ValueError: Invalid version: specify 'v2' or 'v3'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}