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 }}">

    <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">
    <input type="hidden" name="recaptcha_response_field"

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

    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),
            request.META.get("REMOTE_ADDR", None))

        if not captcha_response.is_valid:
            captcha_error = "&error=%s" % captcha_response.error_code
            # 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},

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.