django - 验证码 django-simple-captcha 使用简介

来源:互联网 发布:乐视网络电视直播软件 编辑:程序博客网 时间:2024/05/09 16:30

用了一段时间django-simple-captcha,谈谈体会:

一句话:不好用, 但实在没办法工作中就是要用它,而且发现有些网站也是用的它, 深入学习了下, 发现不是人家不好用而是自己功力不够,还是太菜奋斗

环境:

python:2.7 django: 1.8.3 django-simple-captcha: 0.4.6

django-simple-captcha

下载地址:

https://github.com/mbi/django-simple-captcha
文档:
http://django-simple-captcha.readthedocs.org/

配置settings.py

INSTALLED_APPS = (    'captcha',)# django_simple_captcha 验证码配置 # 格式CAPTCHA_OUTPUT_FORMAT = u'%(text_field)s %(hidden_field)s %(image)s'# 噪点样式CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_null', # 没有样式    # 'captcha.helpers.noise_arcs', # 线    # 'captcha.helpers.noise_dots', # 点)# 图片大小CAPTCHA_IMAGE_SIZE = (100, 25)CAPTCHA_BACKGROUND_COLOR = '#ffffff'CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge' # 图片中的文字为随机英文字母,如 mdsh# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'    # 图片中的文字为数字表达式,如1+2=</span>CAPTCHA_LENGTH = 4 # 字符个数CAPTCHA_TIMEOUT = 1 # 超时(minutes)

forms.py

from django import formsfrom maiziedu.models import UserProfilefrom captcha.fields import CaptchaFieldclass RegisterForm(forms.Form):    '''    注册    '''    username = forms.EmailField(widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "请输入邮箱账号", "value": "", "required": "required",}),                              max_length=50,error_messages={"required": "用户名不能为空",})    password = forms.CharField(widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "请输入密码", "value": "", "required": "required",}),                              min_length=8, max_length=50,error_messages={"required": "密码不能为空",})    # 验证码    captcha = CaptchaField()    def clean(self):                # 验证码        try:                        captcha_x = self.cleaned_data['captcha']                    except Exception as e:            print 'except: '+ str(e)            raise forms.ValidationError(u"验证码有误,请重新输入")         # 用户名        try:                      username=self.cleaned_data['username']        except Exception as e:            print 'except: '+ str(e)            raise forms.ValidationError(u"注册账号需为邮箱格式")            # 登录验证                is_email_exist = UserProfile.objects.filter(email=username).exists()         is_username_exist = UserProfile.objects.filter(username=username).exists()         if is_username_exist or is_email_exist:            raise forms.ValidationError(u"该账号已被注册")        # 密码        try:            password=self.cleaned_data['password']        except Exception as e:            print 'except: '+ str(e)            raise forms.ValidationError(u"请输入至少8位密码");        return self.cleaned_data  
从上面看出clean在cleaned_data会验证验证码,包括验证码是否正确,是否为空,是否过期

views.py

# 注册# 改为ajax post def register(request):    if request.method == 'POST':        # 验证码        print 'captcha_0: ' + request.POST.get('captcha_0')        print 'captcha_1: ' + request.POST.get('captcha_1')        try:            reg_form = RegisterForm(request.POST)        except Exception as e:            print str(e)            # 登录失败 返回错误提示                err = "注册失败,请重试"            return result_response(request, err)         if reg_form.is_valid():            print "register success"            try:                username = reg_form.cleaned_data['username']                password = reg_form.cleaned_data['password']                user = UserProfile.objects.create(username = username, email = username,                   password = make_password(password), is_active = True)                user.save()                user.backend = 'django.contrib.auth.backends.ModelBackend' # 指定默认的登录验证方式                # 验证成功登录                auth.login(request, user)                return result_response(request, "")            except Exception as e:                print str(e)                setFormTips(reg_form, "注册失败,请重试")        else:            print "register failed"            if request.POST.get('captcha_1') == "":                setFormTips(reg_form, "验证码不能为空")         # 登录失败 返回错误提示            err = getFormTips(reg_form)        return result_response(request, err)     else:        reg_form = RegisterForm()        return render(request, 'index.html', locals())

html 模板中显示验证码

有两种方法可以在html显示在验证码

第一种:

{{ reg_form.captcha }}
这种方法对页面的适应性不太好,如上面模板变量生成html如下:
<input autocomplete="off" id="id_captcha_1" name="captcha_1" type="text"><input id="id_captcha_0" name="captcha_0" type="hidden" value="e91228ab45df7338b59b64cb0eae1b60a48fd125"><img src="/%2Fimage/e91228ab45df7338b59b64cb0eae1b60a48fd125/" alt="captcha" class="captcha">

第二种:

views.pyfrom captcha.models import CaptchaStorefrom captcha.helpers import captcha_image_urlhashkey = CaptchaStore.generate_key()imgage_url = captcha_image_url(hashkey)
<input type="text"  id="id_reg_captcha_1" name="captcha_1" class="form-control form-control-captcha fl" placeholder="请输入验证码"><span class="v5-yzm fr"><a href="#" class="next-captcha"><img src="{{ imgage_url }}" class="captcha" alt="captcha">换一张</a></span><input id="id_reg_captcha_0" name="captcha_0" type="hidden" value="{{ hashkey }}">
这种方法解决了第一种方法弊端,同时这种方法给刷新难验证码提供了方便

提交带验证码的表单

方法一: submit , 很简单这里不详述
方法二:ajax post
// 注册并登录  $("#regbtn").click(function(){      var username  = $("#id_reg_username").val();      var password  = $("#id_reg_password").val();      id_captcha_0 = $("#id_reg_captcha_0");      id_captcha_1 = $("#id_reg_captcha_1");      var captcha_1 = id_captcha_1.val();      var captcha_0 = id_captcha_0.val();      var mydata = {          "username": username,          "password": password,          "captcha_0": captcha_0,          "captcha_1": captcha_1      };      if (captcha_1.length==0) {          show_reg_tips("请输入验证码");          return;      }      if (username.length==0 || password.length==0) {          show_reg_tips("帐号密码不能为空");          return;      }            $.ajax({          type: "post",          data: mydata,          url: "{% url 'register' %}",          dataType: "json",          success: function(json){              console.log("ajax register success!");              var status = json['status'];              var error = json['error'];              var new_cptcha_key = json['new_cptch_key'];              var new_cptcha_image = json['new_cptch_image'];               // 重新设置验证码              img = $(".captcha");              id_captcha_0.attr("value", new_cptcha_key);              img.attr("src", new_cptcha_image);          },          error: function(err){              console.log("ajax register err!");              console.log(err);          },          complete: function(){          }      });

后台表单校验

见上 views.py

刷新验证码

前台js

  // 刷新验证码  $(".next-captcha").click(function(){      $.getJSON("{% url 'refresh-captcha' %}", function(json) {          // This should update your captcha image src and captcha hidden input          // debugger;          var status = json['status'];          var new_cptch_key = json['new_cptch_key'];          var new_cptch_image = json['new_cptch_image'];          id_captcha_0 = $("#id_reg_captcha_0");          img = $(".captcha");          id_captcha_0.attr("value", new_cptch_key);          img.attr("src", new_cptch_image);      });        });

后台

# 刷新验证码def refresh_captcha(request):    to_json_response = dict()    to_json_response['status'] = 1    to_json_response['new_cptch_key'] = CaptchaStore.generate_key()    to_json_response['new_cptch_image'] = captcha_image_url(to_json_response['new_cptch_key'])    return HttpResponse(json.dumps(to_json_response), content_type='application/json')


1 0