************************************* reCAPTCHA integration in Django forms ************************************* .. module:: django_recaptcha_field :Latest release: |release| :Download: ``_ :Development: ``_ :Author: `2degrees Limited `_ This is the easy-to-use, highly extensible and well documented `reCAPTCHA `_ plugin for Django forms based on the :mod:`recaptcha` Python client. This library lets your add a reCAPTCHA field to any form class. This field is rendered with a widget that supports non-JavaScript challenges and `customization `_. Tutorial ======== Before you can create form classes that have a reCAPTCHA field, you need a :class:`recaptcha.RecaptchaClient` instance which can be created as follows:: from recaptcha import RecaptchaClient recaptcha_client = RecaptchaClient('private key', 'public key') You can then use :func:`create_form_subclass_with_recaptcha` to create a derivative form class with a reCAPTCHA field like so:: from django_recaptcha_field import create_form_subclass_with_recaptcha from my_app.forms import MyForm MyRecaptchaProtectedForm = create_form_subclass_with_recaptcha( MyForm, recaptcha_client, ) Except for the widget and the required state of the field, you can override other field attributes such as the label and the error messages:: MyRecaptchaProtectedForm = create_form_subclass_with_recaptcha( MyForm, recaptcha_client, {'label': 'Are you human?'}, ) The resulting class requires the request as the first argument when initialized and any additional arguments will be passed on to the constructor of the base form class. The request is required to extract data necessary for the rendering and validation of the field; namely, the remote IP address and whether such a request was made over SSL. Validation ---------- Forms can be validated as usual:: def my_view(request): if request.method == 'POST': form = MyRecaptchaProtectedForm(request, request.POST) if form.is_valid(): process_form_data(form.cleaned_data) else: form = MyRecaptchaProtectedForm(request) # (...) return response with one caveat: Some :mod:`recaptcha` exceptions may propagate through ``form.is_valid()`` upon validation of the reCAPTCHA field. This is intended to give developers control over the handling of the different errors that may occur. The field handles :exc:`recaptcha.RecaptchaInvalidChallengeError` by turning it into a validation error. All the other exceptions, such as :exc:`recaptcha.RecaptchaUnreachableError`, will propagate. So views using these form subclasses may look like this:: from logging import getLogger from django.contrib import messages LOGGER = getLogger(__name__) def my_view(request): if request.method == 'POST': form = MyRecaptchaProtectedForm(request, request.POST) try: is_form_valid = form.is_valid() except RecaptchaUnreachableError: # Bypass reCAPTCHA silently form = MyForm(request.POST) is_form_valid = form.is_valid() except RecaptchaException as exc: LOGGER.exception(exc) messages.add_message(request, messages.ERROR, 'Try again later') form = None is_form_valid = False if is_form_valid: process_form_data(form.cleaned_data) else: form = MyRecaptchaProtectedForm(request) # (...) return response Presentation ------------ The widget for the reCAPTCHA field will make sure that the reCAPTCHA challenge is transmitted over SSL if the request was made over SSL, and vice versa. If you'd like to `customize `_ the challenge, you'd need to set the so-called ``RecaptchaOptions`` on the client. See: :class:`recaptcha.RecaptchaClient`. Client API ========== .. autofunction:: create_form_subclass_with_recaptcha Support ======= For general reCAPTCHA support, please visit the `reCAPTCHA developers' site `_. Please visit the :mod:`recaptcha` library documentation if you require any assistance with it. For suggestions and questions about this library, please use our `2degrees-floss mailing list `_. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search`