django-simple-captcha 验证码插件 和自己实现验证码的

第三方验证码插件的使用

官方文档:http://django-simple-captcha.readthedocs.io/en/latest/usage.html#installation

github:https://github.com/mbi/django-simple-captcha

django-simple-captcha 一个很简单的django验证组件,实现原理是数据库中生成key和随机字符,然后将key与sn存入数据库,用户提交时根据key去数据库中查询比对是否正确,没有使用常用的cookies session, 也挺简单,每个验证码都有过期时间,程序会自动清除过期的验证码

django 版本:1.9.1

安装
pip install  django-simple-captcha==0.4.6
在setting 中配置
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'captcha',
]
url中的配置

加入url(r'^captcha/', include('captcha.urls')),


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^captcha/', include('captcha.urls')),
]
数据库的迁移 

makemigrations
migrate
app下自定义froms.py文件,创建一个注册form

from django import forms
from captcha.fields import CaptchaField

class RegisterForm(forms.Form):
    email = forms.EmailField(required=True)
    password = forms.CharField(required=True, min_length=5)
    captcha = CaptchaField(error_messages={"invalid": u"验证码错误"})
视图函数中处理
class RegisterView(View):
    """注册视图"""

    def get(self, request):
        register_form = Registerform()  # 获取表单对象  然后返回前端
        return render(request, 'register.html', {'register_form': register_form})

    def post(self, request):
        print(request.POST)  #打印下提交的数据
        register_form = Registerform(request.POST)
        if register_form.is_valid():
            pass
        else:
            print(register_form.errors)
前端处理  在form表单中引用这个变量
{{ register_form.captcha }}
在用js实现点击验证码 就能进行切换
支持大小写 
在前端生成的内容 :
               <label>验&nbsp;证&nbsp;码</label>
                            <img src="/captcha/image/d8826580b3125692f6e2f55eef81d906cc0b5d8e/" alt="captcha" class="captcha" /> <input id="id_captcha_0" name="captcha_0" type="hidden" value="d8826580b3125692f6e2f55eef81d906cc0b5d8e" /> <input autocomplete="off" id="id_captcha_1" name="captcha_1" type="text" />

下面是自己实现的验证码

依赖pillow库

生成验证码代码:

# coding=utf-8
import random
import string
from PIL import Image, ImageDraw, ImageFilter, ImageFont
import io  # python3 中是io  pytho2 中是 stringIo


# image 负责处理图片
# ImageDraw 负责处理画笔
# ImageFont 负责处理画笔
# ImageFilter 负责处理 过滤镜
def create_check():
    # 1 创建画布
    img = Image.new("RGB", (150, 50), (255, 255, 255))
    """
    第一个参数: 代表要采用RGB的颜色模式
    第二个参数:代表图片的大小
    第三个参数:具体的图片的颜色
    """
    # 2 创建画笔
    draw = ImageDraw.Draw(img)
    # 3 绘制线条和点
    #  绘制线
    for i in range(random.randint(1, 10)):
        # for i in range(5):
        draw.line(
            # 在绘制线条的时候 是需要两个点确定一条直线的 每个点靠x y 两个值来确定位置的
            [
                (random.randint(1, 150), random.randint(1, 150)),  # 这个是一个 x 和 y 确定的座标的位置
                # 第二个x 和 要确定的 座标的位置  两个座标 确定了一条直线
                (random.randint(1, 150), random.randint(1, 150))
            ],
            fill=(0, 0, 0)
        )
    # 开始绘制点
    for j in range(1000):
        draw.point(
            [
                random.randint(1, 150),
                random.randint(1, 150)
            ],
            fill=(0, 0, 0)
        )
    # 4 绘制文字
    str_temp = string.ascii_letters  # 生成大小写字母
    digtial_temp = string.digits  # 生成数字  0-9
    font_list = list(str_temp + digtial_temp)  # 组合成一个list列表
    c_chars = "".join(random.sample(font_list, 5))  # 从指定的列表中随机的返回固定的长度的字符
    # 5 绘制字体
    font = ImageFont.truetype("simsun", 32)  # 这个字体是怎么设置的????? 需要使用什么样的 字体
    draw.text((5, 5), c_chars, font=font, fill="green")
    """
    第一个参数:代表文字的位置  距离上和左的距离
    第二个参数:代表文字的内容
    第三个参数:代表文字的字体和大小
    第四个参数:代表字体的颜色
    """
    # 5 定义扭曲的参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 2)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,  # 总体的比列
              float(random.randint(1, 1)) / 500,
              ]
    # 6 使用滤镜 添加滤镜
    img = img.transform((150, 50), Image.PERSPECTIVE, params)
    # 扭曲的范围   扭曲的样式   扭曲的参数
    # 进行扭曲
    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    # 展示画布
    # img.save("demo.jpg")  # 保存文件   返回图片的内容 然后把内容保存在内存中 这里就不再在保存在本地了
    # img.show()  # 这个是展示生成的图片的
    return img, c_chars  # 给调用者返回这个img  也可以不用返回  直接生成在内存中

在视图函数中调用验证码

# 导入工具包中的生成图片的方法    
from utils import check_code
import io  # 可以把图片保存咋内存中

# 调用生成验证码的方法 并把验证码存入内存中  返回给前端
def tupian(request):
    """获取验证码图片"""
    img, c_chars = check_code.create_check()
    # 上面调用了生成图片的函数 返回了生成图片的对象 和生成图片上面的文字
    stream = io.BytesIO()  # 返回一个内存的字节流对象
    img.save(stream, 'png')  # 把图片保存在内存中 然后 直接从内存中读取返回
    # 把生成图片的字母保存在session
    request.session['c_chars'] = c_chars
    return HttpResponse(stream.getvalue())  # 直接去内存中 取出对象 然后进行返回


# 验证提交上来的验证码    
def yanzhengma(request):
    """返回验证码表单"""
    if request.method == 'GET':
        return render(request, "验证码.html")
    elif request.method == 'POST':
        yanzhengma = request.POST.get("yanzhengma")
        # 获取session 中保存的验证码的信息  然后和用户提交上来的进行对比 
        c_chars = request.session['c_chars']
        # 把session中的 和获取到的字符串全部 变成 小写 来进行对比
        yanzhengma = yanzhengma.lower()
        c_chars = c_chars.lower()
        if yanzhengma == c_chars:
            return HttpResponse("登陆成功".encode())
        else:
            return HttpResponse("登陆失败".encode())

前端处理

<body>
    <h3>验证码表单</h3>
    <div class="container">
        <form action="/login/yanzhengma/" method="POST">
            <input type="text" name="yanzhengma" id="yanzhengma">
            <input type="file" name="file" id="file">
            <input type="submit" id="submit">
        </form>

    </div>
    <div id="see">
        <h5>验证码</h5>
        {% comment %}在这里请求图片的时候就会返回这个视图函数读取的内容{% endcomment %}
        <img src="/login/tupian/" alt="" onclick="change_yanzhengma(this)">
    </div>
    <script>
        //点击图片换验证码
        function change_yanzhengma(ths) {
            //点击图片进行切换 给img加上一个点击事件  然后
            // 然后去重新给这个src 来赋值  获取原来的再加上个?
            //动态的去改变URL的地址
            ths.src = ths.src + "?";
        }
    </script>
</body>
发布了54 篇原创文章 · 获赞 7 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章