Login

RecaptchaForm

Author:
oggy
Posted:
June 17, 2008
Language:
Python
Version:
.96
Score:
1 (after 3 ratings)

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

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

wuyuntao (on July 17, 2008):

Great snippets, thank you

#

Please login first before commenting.