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')