There already is a snippet on here that shows how to use reCAPTCHA with Django, but being the lazya-- that I am, I wanted the form to:
-
display the captcha when as_table is used
-
handle captcha validation for me
So RecaptchaForm does the trick. Just subclass from it and voila, your form will include reCAPTCHA validation. Other than that, you need to
-
be on Django trunk version (or use clean_data instead of cleaned_data for 0.96)
-
set RECAPTCHA_PRIVATE_KEY and RECAPTCHA_PUBLIC_KEY in your settings.py
-
make sure that the captcha module is available somewhere (i.e. that "import captcha" works)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | from django import newforms as forms
from django.newforms import ValidationError
from django.conf import settings
import captcha
class RecaptchaWidget(forms.Widget):
""" A Widget which "renders" the output of captcha.displayhtml """
def render(self, *args, **kwargs):
return captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY)
class DummyWidget(forms.Widget):
"""
A dummy Widget class for a placeholder input field which will
be created by captcha.displayhtml
"""
# make sure that labels are not displayed either
is_hidden=True
def render(self, *args, **kwargs):
return ''
class RecaptchaForm(forms.Form):
"""
A form class which uses reCAPTCHA for user validation.
If the captcha is not guessed correctly, a ValidationError is raised
for the appropriate field
"""
recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
recaptcha_response_field = forms.CharField(widget=RecaptchaWidget, label='')
def __init__(self, request, *args, **kwargs):
super(RecaptchaForm, self).__init__(*args, **kwargs)
self._request = request
def clean_recaptcha_response_field(self):
if 'recaptcha_challenge_field' in self.cleaned_data:
self.validate_captcha()
return self.cleaned_data['recaptcha_response_field']
def clean_recaptcha_challenge_field(self):
if 'recaptcha_response_field' in self.cleaned_data:
self.validate_captcha()
return self.cleaned_data['recaptcha_challenge_field']
def validate_captcha(self):
rcf = self.cleaned_data['recaptcha_challenge_field']
rrf = self.cleaned_data['recaptcha_response_field']
ip_address = self._request.META['REMOTE_ADDR']
check = captcha.submit(rcf, rrf, settings.RECAPTCHA_PRIVATE_KEY, ip_address)
if not check.is_valid:
raise ValidationError('You have not entered the correct words')
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Great snippets, thank you
#
Please login first before commenting.