1:第一种自定义验证码(推荐)
1 前端: <img id ="img" src="/路由/"> <span {{ dict.error }}</span> 2 前端js刷新验证码: 3 <script> 4 img =document.getElementById("img"); 5 img.onclick = function () { 6 img.src = img.src + "?"; #利用加?来刷新图片生成更换 7 } 8 </script> 9 10 11 12 校验验证码函数: 13 if request.method == "POST": 14 dict = {} #用户返回错误信息 15 # 判断验证码 16 input_code = request.POST.get("code").upper() #输入的验证码 17 obj = F1(request.POST) #输入框的所有数据 18 19 if obj.is_valid() and input_code == request.session["code"]: ##判断输入的值是否等于注册session的验证码(生成随机码的时候已经注册到session) 20 21 # 插入数据库,这里是删除不需要添加到数据表的key 22 obj.cleaned_data.pop("again_password") 23 obj.cleaned_data.pop("code") 24 models.UserInfo.objects.create_user(**obj.cleaned_data) 25 return redirect("/index/login/") #返回页面 26 else: 27 dict["error"] = "验证码不匹配" 28 return render(request,"register.html",{"obj":obj,"dict":dict}) 29 30 31 32 33 验证码生成(直接复制到对应视图最下面): 34 后端视图对应的路由 : 35 36 #验证码: 37 from PIL import Image, ImageDraw, ImageFont, ImageFilter 38 import random 39 40 41 #随机颜色 42 def random_color(): 43 return random.randint(0,255),random.randint(0,255),random.randint(0,255) 44 45 def code(request,width=150, height=35): 46 # with open("1.png", "wb") as f: 47 # 定义一个图片,并且设置参数 48 img_obj = Image.new('RGB', size=(width, height), color=(255, 255, 255)) # 长宽 颜色 49 50 # 创建画笔在画布上 51 draw_obj = ImageDraw.Draw(img_obj) 52 # 自定义字体 53 font_obj = ImageFont.truetype('Monaco.ttf', 28) 54 55 # 写干扰点 56 for i in range(40): 57 draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=random_color()) 58 59 # 写干扰圆圈 60 for i in range(40): 61 draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=random_color()) 62 x = random.randint(0, width) 63 y = random.randint(0, height) 64 draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=random_color()) 65 66 # 画干扰线 67 for i in range(5): 68 x1 = random.randint(0, width) 69 y1 = random.randint(0, height) 70 x2 = random.randint(0, width) 71 y2 = random.randint(0, height) 72 73 draw_obj.line((x1, y1, x2, y2), fill=random_color()) 74 75 img = img_obj.filter(ImageFilter.EDGE_ENHANCE_MORE) 76 77 # 随机字符串 78 for i in range(5): 79 l = chr(random.randint(97, 122)) # 小写字母 80 b = chr(random.randint(65, 90)) # 大学字母 81 n = str(random.randint(0, 9)) 82 83 t = random.choice([b, l, n]) 84 85 # 在text参数设置坐标,字符串,颜色,字体 86 draw_obj.text((i * 30, 0), t, fill=random_color(), font=font_obj) 87 88 #放到session,并且忽略大小写 89 request.session["code"] = "".join(temp).upper() 90 91 #写入内存,显示到网页上 92 f = open("1.png","rb") 93 data =f.read() 94 from io import BytesIO 95 f1 = BytesIO() 96 img_obj.save(f1,format="PNG") 97 image_data = f1.getvalue() 98 99 100 return HttpResponse(image_data,content_type="image/png")
2:第二种验证码(据说有BUG)博主没用过
1) 安装 django-simple-captcha: pip install django-simple-captcha 2)注册captcha INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'captcha', ] 也可以个性化定制,在 settings.py中添加如下代码,详情参考官方文档: # 设置 captcha 图片大小 CAPTCHA_IMAGE_SIZE = (80, 45) # 字符个数 CAPTCHA_LENGTH = 4 # 超时(minutes) CAPTCHA_TIMEOUT = 1 3)创建它的表 python manage.py makemigrations python manage.py migrate 4)添加路由 urlpatterns = [ url('admin/', admin.site.urls), # 图片验证码 路由 url('captcha/', include('captcha.urls')) ] 再添加ajax刷新请求的二级路由,ajxa请求地址: captcha/refresh_captcha/ url('refresh_captcha/', views.refresh_captcha), # 刷新验证码,ajax 5)在form文件中直接导入模块: from captcha.fields import CaptchaField 6)在写的form类下填写生成标签: Captcha = CaptchaField() 7)前端设置跟其他组件一致,存放数据库: obj.cleaned_data.pop("captcha"," ")
ps:django-simple-captcha有一些多余的功能,所以从它的源代码中提取了一部分加以修改,生成了一个简单的验证码模块。在使用django-simple-captcha时发现了一个Bug,
该库使用HttpResponse.write(image_data)的方式返回验证码图片数据,导致验证码图片无法显示,具体原因还不清楚,
不过换成HttpResponse(content=image_data)的方式就好了。这也是我自定义验证码功能的原因。