Pull to refresh

Django-yacaptcha (Yandex captcha) — ленивое надо

Недавно предлагали использовать какую то самописную капчу, но мне в лом. Первое, что я нашел, устанавливаемое без плясок с бубном это django-recaptcha — Гугло капча! Всем она знакома, сука фашистская. Сам много раз вводил эти символы инопланетного Пикассо. В общем не вариант. Вспомнил про яндекс капчу
image
хорошо, просто. Но API смутили меня в ноль, что, куда — курить ман по интеграции автоматизированной картинки влом… ну его. Тут же нашлась либа Yandex cleanweb — просто, удобно...

Интеграция в формы джанго
Берем исходники вышеупомянутой django-recaptcha и делаем свое поле ввода по образу и подобию fields.py:

from django import forms
from django.core import validators
from cleanweb import Cleanweb
from widgets import YaCaptcha
from django.utils.translation import ugettext_lazy as _

class YaCaptchaField(forms.CharField):
    default_error_messages = {
        'required': _(u'This field is required.'),
        'captcha_invalid': _(u'Incorrect, please try again.')
    }

    def __init__(self, *args, **kwargs):
        self.required = True
        self.widget = YaCaptcha()  # код виджета ниже
        super(YaCaptchaField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if value in validators.EMPTY_VALUES:
            return None
        return value

    def validate(self, values):
        super(YaCaptchaField, self).validate(values[0])
        recaptcha_challenge_value = values[0]   # пользовательский ввод 
        recaptcha_response_value = values[1]   # код сессии от яндекса 

        client = Cleanweb(key=self.widget.key)  # либа сэкономившая много минут, спасибо coagulant

        check = client.check_captcha(captcha=recaptcha_response_value, value=recaptcha_challenge_value)
        if not check:
            raise forms.ValidationError(self.error_messages['captcha_invalid'])


далее, нужно сделать вывод проверочной картинки, для этого пилим виджет widgets.py:

from django import forms
from django.conf import settings
from django.template.loader import render_to_string
from cleanweb import Cleanweb

DEFAULT_WIDGET_TEMPLATE = 'widget.html'
WIDGET_TEMPLATE = getattr(settings, "YACAPTCHA_WIDGET_TEMPLATE", DEFAULT_WIDGET_TEMPLATE)


class YaCaptcha(forms.widgets.Widget):
    def __init__(self, key=None, *args, **kwargs):
        self.key = key if key else settings.YACAPTCHA_KEY   # ключ от Yandex cleanweb API  
        super(YaCaptcha, self).__init__(*args, **kwargs)

    # Вывод капчи
    def render(self, name, value, attrs=None):
        client = Cleanweb(key=self.key)
        cap_dict = client.get_captcha()  # Ответ от яндекса в виде словаря
        return render_to_string(WIDGET_TEMPLATE,
                                {'yacaptcha_img_url': cap_dict['url'],
                                 'yacaptcha_response_field': cap_dict['captcha']  # Проверочный код сессии яндекса
                                })

    # Выборка данных из словаря значений формы
    def value_from_datadict(self, data, files, name):
        return [data.get('yacaptcha_challenge_field', None), data.get('yacaptcha_response_field', None)]


ну вот, почти все готово, осталось положить html, в директорию templates widget.html:

<img src="{{ yacaptcha_img_url }}" ><br>  # Картинка
<input type="text" name="yacaptcha_challenge_field" />  # Пользовательский ввод
<input type='hidden' name='yacaptcha_response_field' value="{{ yacaptcha_response_field }}"/>  # Проверочный код сессии яндекса


Проверено на Django 1.4.5, исходники: github.com/avigmati/django-yacaptcha
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.