Django REST reCAPTCHA
Django REST reCAPTCHA v2 and v3 field serializer
Requirements
- Python: 3.10, 3.11, 3.12, 3.13
- Django: 4.2, 5.0, 5.1, 5.2
- DRF: 3.14, 3.15, 3.16
Installation
- Sign up for reCAPTCHA
- Install with
pip install drf-recaptcha - Add
"drf_recaptcha"to yourINSTALLED_APPSsettings. - Set in settings
DRF_RECAPTCHA_SECRET_KEY
INSTALLED_APPS = [
...,
"drf_recaptcha",
...,
]
...
DRF_RECAPTCHA_SECRET_KEY = "YOUR SECRET KEY"
Usage
from rest_framework.serializers import Serializer, ModelSerializer
from drf_recaptcha.fields import ReCaptchaV2Field, ReCaptchaV3Field
from feedback.models import Feedback
class V2Serializer(Serializer):
recaptcha = ReCaptchaV2Field()
...
class GetOTPView(APIView):
def post(self, request):
serializer = V2Serializer(data=request.data, context={"request": request})
serializer.is_valid(raise_exception=True)
...
class V3Serializer(Serializer):
recaptcha = ReCaptchaV3Field(action="example")
...
class V3WithScoreSerializer(Serializer):
recaptcha = ReCaptchaV3Field(
action="example",
required_score=0.6,
)
...
class GetReCaptchaScore(APIView):
def post(self, request):
serializer = V3WithScoreSerializer(data=request.data, context={"request": request})
serializer.is_valid()
score = serializer.fields['recaptcha'].score
...
class FeedbackSerializer(ModelSerializer):
recaptcha = ReCaptchaV2Field()
class Meta:
model = Feedback
fields = ("phone", "full_name", "email", "comment", "recaptcha")
def validate(self, attrs):
attrs.pop("recaptcha")
...
return attrs
class DynamicContextSecretKey(APIView):
def post(self, request):
if request.platform == "android":
recaptcha_secret_key = "SPECIAL_FOR_ANDROID"
else:
recaptcha_secret_key = "SPECIAL_FOR_IOS"
serializer = WithReCaptchaSerializer(
data=request.data,
context={
"request": request,
"recaptcha_secret_key": recaptcha_secret_key,
},
)
serializer.is_valid(raise_exception=True)
...
class DynamicContextSecretKey(GenericAPIView):
serializer_class = WithReCaptchaSerializer
def get_serializer_context(self):
if self.request.platform == "android":
recaptcha_secret_key = "SPECIAL_FOR_ANDROID"
else:
recaptcha_secret_key = "SPECIAL_FOR_IOS"
context = super().get_serializer_context()
context.update({"recaptcha_secret_key": recaptcha_secret_key})
return context
class MobileSerializer(Serializer):
recaptcha = ReCaptchaV3Field(secret_key="SPECIAL_MOBILE_KEY", action="feedback")
...
Settings
DRF_RECAPTCHA_SECRET_KEY - set your Google reCAPTCHA secret key. Type: str.
DRF_RECAPTCHA_DEFAULT_V3_SCORE - by default: 0.5. Type: float.
DRF_RECAPTCHA_ACTION_V3_SCORES - by default: {}. Type: dict. You can define specific score for each action e.g.
{"login": 0.6, "feedback": 0.3}
DRF_RECAPTCHA_DOMAIN - by default: www.google.com. Type: str.
DRF_RECAPTCHA_PROXY - by default: {}. Type: dict. e.g.
{'http': 'http://127.0.0.1:8000', 'https': 'https://127.0.0.1:8000'}
DRF_RECAPTCHA_VERIFY_REQUEST_TIMEOUT - by default: 10. Type: int.
Priority of secret_key value
- settings
DRF_RECAPTCHA_SECRET_KEY - the argument
secret_keyof field - request.context["recaptcha_secret_key"]
Silence the check error
If you need to disable the error, you can do so using the django settings.
SILENCED_SYSTEM_CHECKS = ['drf_recaptcha.checks.recaptcha_system_check']
reCAPTCHA v3
Validation is passed if the score value returned by Google is greater than or equal to required score.
Required score value: 0.0 - 1.0
Priority of score value
If not defined or zero in current item then value from next item.
- Value for action in settings
DRF_RECAPTCHA_ACTION_V3_SCORES - Value in argument
required_scoreof field - Default value in settings
DRF_RECAPTCHA_DEFAULT_V3_SCORE - Default value
0.5
Testing
Set DRF_RECAPTCHA_TESTING=True in settings, no request to Google, no warnings, DRF_RECAPTCHA_SECRET_KEY is not
required, set returning verification result in setting below.
DRF_RECAPTCHA_TESTING_PASS=True|False - all responses are pass, default True.
Use from django.test import override_settings
Credits
reCAPTCHA copyright 2012 Google.
Release files for drf-recaptcha 4.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drf_recaptcha-4.0.3.tar.gz | 7.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drf_recaptcha-4.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.2 kB
Release files / drf_recaptcha-4.0.3.tar.gz
| Download URL | drf_recaptcha-4.0.3.tar.gz |
|---|---|
| Size | 7.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c39a406d7a22134c23438a7feef93c2d18ea2c9e3072da6de91aa6ce7d81cc14
|
|
BLAKE2b-256 checksum How to use checksums |
e6f6d155de397cee001be425f9d6790b83acbb9d54bd18e984c53b2d445c8cda
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2025.
Transparency logRelease files / drf_recaptcha-4.0.3-py3-none-any.whl
| Download URL | drf_recaptcha-4.0.3-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eb0762c22bc1d4b877d4ff277de3baa1d7581a5126160d3c2717cba6d692b0ac
|
|
BLAKE2b-256 checksum How to use checksums |
a8ac1680d655f1b77e0bbbd617ae6f13bbaf75c8b5aec048dfa6576b2615b0e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2025.
Transparency log