除此之外,reCAPTCHA 还有一项非常公益的设计。虽然 OCR (全称 Optical Character Recognitio,中译光学字元识别)早已被投入使用,但是对那些印刷模糊或分辨度不足的实体书籍而言,OCR 的识别率难说完美。而 reCAPTCHA 将这些上无法由电脑自动识别的单词扫描下来,以图片的形式存入数据库,并在网络上以验证码(CAPTCHA)的形式交由人类来破译,而破译的结果将被用于帮助世界上的实体书加快数字化的进程。
你可能会问,既然电脑无法识别这些单词,那么 reCAPTCHA 系统又怎么知道用户填写的是正确的验证码呢?reCAPTCHA 的网站上有详细的解释。
一个不能被 OCR 正确识别的新单词,总是会和另一个已知答案的单词一起提交给用户。接下来用户需要同时识别这两个单词。如果用户正确识别出其中已知答案的那个单词,系统即假设用户所识别出的未知答案的新单词也可能是正确的。如果其他的用户也识别出相同的答案,系统则逐步提高这种可能性。最终当这种可能性超过某个阈值时,系统就可以将其认作已知答案的单词了。
言归正传,reCAPTCHA 有丰富的 API,包括对 PHP、JAVA、Ruby,自然还有 Python 的支持。如果要在 Django 上使用 reCAPTCHA,我们可以从 PyPI 下载 reCAPTCHA 的 Python 客户端,或者直接用 easy_install 安装。
# easy_install recaptcha-client
不知道为什么,虽然安装成功了,但是我不能导入 recaptcha 模块(wyt:import captcha 或 import recaptcha 都没有用,哪位如果顺利导入过的话,能不能分享一下你的经验呢?先谢了),所以我是把 egg 中的脚本直接复制到我的 Django 项目目录下了。
接下来,我们需要在 reCAPTCHA 注册并申请一对公钥/私钥,并将其保存在 settings.py 中。
settings.py
1 # reCAPTCHA keys
2 RECAPTCHA_PUBLIC_KEY = "6LdqgAIAAAUSHDmo4IIBmsjUsduAUMUoBDZc3J_T"
3 RECAPTCHA_PRIVATE_KEY = "6LdqgAIAAbjsJKLbj2KOjPO6D4isfJ_AzLSO_256"
然后,我们要为注册表单添加验证码了。在 Django Snippets 上,oggy 已经将 reCAPTCHA 抽象成一个 RecaptchaForm 类,所以我们只要让注册表单(Registration Form)继承这个类,就可以为注册表单添加验证码的功能了。由于 Django newform 默认是根据 field 的定义顺序来生成表单,所以在继承 RecaptchaForm 的时候,也应该把它放在最后继承。
recaptcha/forms.py
01 from django import newforms as forms
02 from django.newforms import ValidationError
03 from django.conf import settings
04 from recaptcha import captcha
05
06
07 class RecaptchaWidget(forms.Widget):
08 """ A Widget which "renders" the output of captcha.displayhtml """
09 def render(self, *args, **kwargs):
10 return captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY)
11
12 class DummyWidget(forms.Widget):
13 """
14 A dummy Widget class for a placeholder input field which will
15 be created by captcha.displayhtml
16
17 """
18 # make sure that labels are not displayed either
19 is_hidden=True
20 def render(self, *args, **kwargs):
21 return ''
22
23 class RecaptchaForm(forms.Form):
24 """
25 A form class which uses reCAPTCHA for user validation.
26
27 If the captcha is not guessed correctly, a ValidationError is raised
28 for the appropriate field
29 """
30 recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
31 recaptcha_response_field = forms.CharField(widget=RecaptchaWidget, label='')
32
33 def __init__(self, request, *args, **kwargs):
34 super(RecaptchaForm, self).__init__(*args, **kwargs)
35 self._request = request
36
37 def clean_recaptcha_response_field(self):
38 if 'recaptcha_challenge_field' in self.cleaned_data:
39 self.validate_captcha()
40 return self.cleaned_data['recaptcha_response_field']
41
42 def clean_recaptcha_challenge_field(self):
43 if 'recaptcha_response_field' in self.cleaned_data:
44 self.validate_captcha()
45 return self.cleaned_data['recaptcha_challenge_field']
46
47 def validate_captcha(self):
48 rcf = self.cleaned_data['recaptcha_challenge_field']
49 rrf = self.cleaned_data['recaptcha_response_field']
50 ip_address = self._request.META['REMOTE_ADDR']
51 check = captcha.submit(rcf, rrf, settings.RECAPTCHA_PRIVATE_KEY, ip_address)
52 if not check.is_valid:
53 raise ValidationError('You have not entered the correct words')
user/forms.py
01 from myproject.recaptcha.forms import RecaptchaForm
02
03 class RegistrationForm(forms.Form):
04 """
05 Form for registering a new user account.
06
07 """
08
09 class RegistrationFormWithRecaptcha(RegistrationForm, RecaptchaForm):
10 """
11 Subclass of ``RegistrationForm`` and ``RecaptchaForm`` which can tell whether its user
12 is a human or a computer.
13
14 """



2 评论:
我很想用,但是我是新学着用django的表单处理的,博主能不能说说说怎么在一个已有的django项目里集成这个东西呢?
@燕子乡
就像上面说的,让你的注册表单继承RecaptchaForm就好了
发表评论
欢迎留言