суббота, 27 ноября 2010 г.

Используем reCaptcha в приложениях django

Progg it

Сегодня мы поговорим об использовании reCaptcha в django-приложениях. Не буду говорить о достоинствах reCaptcha, думаю, что они и так понятны. Итак, наша задача состоит в том, чтобы как можно меньшими усилиями прикрутить reCaptcha к нашему приложению. Для этого нам потребуется выполнить следующее:

  • Зарегистрироваться здесь и получить наши ключи
  • Сделать приложение django, которое будет отвечать за взаимодействие с серверами reCaptcha, и позволит использовать ее в наших формах
  • Включить ее в одну из форм приложения, где она требуется

Шаг 1. Регистрация

Думаю, что как регистрироваться может разобраться любой из тех, кто понял что ему нужна reCaptcha в разрабатываемом приложении. Главное получить и сохранить ключи для вашего приложения. В зависимости от вашего желания вы можете получить ключи на конкретный адрес, или на все. Отмечу сразу, что любая пара валидных ключей корректно работает с адреса 127.0.0.1, что позволяет писать и отлаживать приложение на локальной машине, и не огребать при этом лишних проблем. Полученные ключи пропишем в settings.py примерно таким образом:

  ...
  #reCAPTCHA keys  
  RECAPTCHA_PUBLIC_KEY = < ПУБЛИЧНЫЙ КЛЮЧ > 
  RECAPTCHA_PRIVATE_KEY = < СЕКРЕТНЫЙ КЛЮЧ >
  ... 

На этом подготовительный этап закончен.

Шаг 2. Приложение django

Создадим приложение django, которое будет предоставлять функциональность другим приложениям и скрывать детали взаимодействия с сервисом reCaptcha. Скажу честно, что я взял приложение marcofucci, и только слегка его модифицировал.

Для начала необходимо скачать recaptcha-client. При этом нам потребуется только captcha.py из клиента. Берем этот файлик и кладем в наше приложение. Он обеспечит нам базовое взаимодействие с сервисом. Теперь нам необходимо сделать виджет и поле формы, для того, чтобы можно было легко использовать reCaptcha в нашем приложении. Приведу сразу код, который взят у marcofucci:

widgets.py

  1:  # -*- coding: utf-8 -*-  
  2:  from django import forms  
  3:  from django.utils.safestring import mark_safe  
  4:  from django.conf import settings  
  5:  from recaptcha import captcha  
  6:  class ReCaptcha(forms.widgets.Widget):  
  7:    recaptcha_challenge_name = 'recaptcha_challenge_field'  
  8:    recaptcha_response_name = 'recaptcha_response_field'  
  9:    def render(self, name, value, attrs=None):  
  10:      return mark_safe(u'%s' % captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY))  
  11:    def value_from_datadict(self, data, files, name):  
  12:      return [data.get(self.recaptcha_challenge_name, None),   
  13:        data.get(self.recaptcha_response_name, None)]   

forms.py

  1:  # -*- coding: utf-8 -*-  
  2:  from django.conf import settings  
  3:  from django import forms  
  4:  from django.utils.encoding import smart_unicode 
  5:  from django.utils.translation import ugettext_lazy as _  
  6:  from recaptcha.widgets import ReCaptcha  
  7:  from recaptcha import captcha  
  8:  class ReCaptchaField(forms.CharField):  
  9:    default_error_messages = {  
  10:      'captcha_invalid': _(u'Invalid captcha')  
  11:    }  
  12:    def __init__(self, *args, **kwargs):  
  13:      self.widget = ReCaptcha  
  14:      self.required = True  
  15:      super(ReCaptchaField, self).__init__(*args, **kwargs)  
  16:    def clean(self, values):  
  17:      super(ReCaptchaField, self).clean(values[1])  
  18:      recaptcha_challenge_value = smart_unicode(values[0])  
  19:      recaptcha_response_value = smart_unicode(values[1])  
  20:      check_captcha = captcha.submit(recaptcha_challenge_value,   
  21:        recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})  
  22:      if not check_captcha.is_valid:  
  23:        raise forms.util.ValidationError(self.error_messages['captcha_invalid'])  
  24:      return values[0] 

Теперь мы готовы к использованию reCaptcha в нашем приложении.

Шаг 3. Использование

Использование сводится к созданию в форме соответствующего поля, и вполне обычной обработки формы в стиле django. Напиример так:

  1:  class RegistrationForm(ModelForm):  
  2:       recaptcha = ReCaptchaField(error_messages = {  
  3:            'required': u'Это поле должно быть заполнено',            
  4:            'invalid' : u'Указанное значение было неверно'  
  5:            })  
  6:       class Meta:  
  7:            model = UserData  
  8:            fields = (  
  9:                 'email',  
  10:                 'fio',  
  11:                 'phone',  
  12:                 'company',  
  13:                 'address'  
  14:            )  

В данном случае у меня имеется форма по модели, к которой добавлено поле с reCaptcha. Использование формы в функции вида приводить не буду, так как оно ничем не отличается от стандартного, достаточно заглянуть в документацию

4 комментария:

  1. ...нам потребуется только captcha.py из клиента...
    ...from recaptcha.widgets import ReCaptcha...

    ОтветитьУдалить
  2. Я думаю надо было упоминуть о том что в settings.py необходимы константы RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY

    ОтветитьУдалить
  3. Ай, я слепой :) Извиняюсь.

    ОтветитьУдалить
  4. ты вообще идиот, прежде чем писать статьи, научись их писать

    ОтветитьУдалить