11Aug

Adding ReCaptcha to Django

Posted by Elf Sternberg as django, python, web development

I learned today how to enable ReCaptcha for Django. It’s fairly trivial. I’ll show you how to enable this for account registration.

First, go and create a key pair for your site. You don’t even have to give them an email address, which is nice.

Install the recaptcha client library on your site:

pip install recaptcha-client

You’ll have to override or replace any registration templates you have, and add this to the form, somewhere in the form (usually, right above the submit button):

<p>Please be a human, and not some spamming robot:</p>

<script type="text/javascript"
    src="http://www.google.com/recaptcha/api/challenge?k=YOUR_RECAPTCHA_PUBLIC_KEY{{ captcha_error }}">
</script>

<noscript>
    <iframe src="http://www.google.com/recaptcha/api/noscript?k=YOUR_RECAPTCHA_PUBLIC_KEY{{ captcha_error }}"
        height="300" width="500" frameborder="0"></iframe><br>
    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
    </textarea>
    <input type="hidden" name="recaptcha_response_field"
        value="manual_challenge">
</noscript>

Add your private key to your settings.py file, and code your “accounts.view.create” this way:

def create(request, template_name='accounts/create.html',
    redirect_field_name=REDIRECT_FIELD_NAME):

    user_form = None
    captcha_error = ""
    redirect_to = request.REQUEST.get(redirect_field_name, '')

    if request.method == "POST":
        captcha_response = captcha.submit(
            request.POST.get("recaptcha_challenge_field", None),
            request.POST.get("recaptcha_response_field", None),
            settings.RECAPTCHA_PRIVATE_KEY,
            request.META.get("REMOTE_ADDR", None))

        if not captcha_response.is_valid:
            captcha_error = "&error=%s" % captcha_response.error_code
        else:
            # perform other registration checks as needed...
            # success!
            return HttpResponseRedirect(redirect_to)

    if not user_form:
        user_form = UserForm(prefix="user")

    return render_to_response(template_name, {
        'captcha_error': captcha_error,
        'user_form': user_form},
        context_instance=RequestContext(request))

And that’s it. You have ReCaptcha enabled. I see that the python library includes an HTML generator, but it’s for recaptcha.net, and I decided to use the newer google addresses.

By the way, I’m not sure why, but I much prefer the form = None sentinel method of checking for form initialization. I think it’s a lot cleaner than a metric ton of else statements.

4 Responses to Adding ReCaptcha to Django

Samus_

August 11th, 2010 at 8:15 pm

> I’m not sure why, but I much prefer the form = None sentinel method of checking for form initialization

I like locals()

Elf Sternberg

August 11th, 2010 at 8:17 pm

That sounds like a sure way to get yourself into trouble.

what

August 11th, 2010 at 8:31 pm

locals is also like 0.00001% slower, so I use the form = None way

xlevus

August 12th, 2010 at 2:25 pm

Well it’s not very well done. Everything should be rendered and validated by the Form either through a custom clean method or ideally a custom Form Field.

Here’s a better example: http://lobstertech.com/2008/aug/27/integrating_django_recaptcha/

Comment Form

Subscribe to Feed

Categories

Calendar

August 2010
M T W T F S S
« Jul   Sep »
 1
2345678
9101112131415
16171819202122
23242526272829
3031