django框架登陆图片验证码

1、引入字体(不必要)

注:字体可以在浏览器上搜索ttf进行下载

2、创建code.py

import random
from PIL import Image,ImageDraw,ImageFont,ImageFilter

def check_code(width=120,height=30,char_length=5,font_file='kai.ttf',font_size=28):
    # kai.ttf自己下载字体的文件名
    code=[]
    img=Image.new(mode="RGB",size=(width,height),color=(255,255,255))
    draw=ImageDraw.Draw(img,mode="RGB")

    def rndChar():
        "生成随机字母"
        return chr(random.randint(65,90))
        # 随机生成数字
        # return str(random.randint(0,9))

    def rndColor():
        "生成随机颜色"
        return (random.randint(0,255),random.randint(10,255),random.randint(64,255))

    "写文字"
    font=ImageFont.truetype(font_file,font_size)
    for i in range(char_length):
        char=rndChar()
        code.append(char)
        h=random.randint(0,4)
        draw.text([i*width/char_length,h],char,font=font,fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0,width),random.randint(0,height)],fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        x=random.randint(0,width)
        y=random.randint(0,height)
        draw.arc((x,y,x+4,y+4),0,90,fill=rndColor())
    # 写干扰线
    for i in range(5):
        x1=random.randint(0,width)
        y1=random.randint(0,height)
        x2=random.randint(0,width)
        y2=random.randint(0,height)
        draw.line((x1,y1,x2,y2),fill=rndColor())

    img=img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img,''.join(code)






3、创建url

 path('image/code/',account.image_code),

4、在中间件中设置(排除登陆和验证码的情况)

  if request.path_info in ["/login/","/image/code/"]:
            return

5、html前端页面

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }

        .account h2 {
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
<div class="account">
    <h2>用户登陆</h2>
    <form method="post" novalidate>
        {#        novalidate去掉自身所带的错误提示没填东西直接提交#}
        {#        使用post请求需要加上#}
        {% csrf_token %}
        <div class="form-group">
            <label>用户名</label>
            {{ form.username }}
            <span style="color: red">{{ form.username.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label>密码</label>
            {{ form.password }}
            <span style="color: red">{{ form.password.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label for="id_code">图片验证码</label>
            <div class="row">
                <div class="col-xs-7">
{#                    <input type="text" name="code" class="form-control" placeholder="请输入图片验证码" required="" id="id_code">#}
                    {{ form.code }}
                    <span style="color: red;">{{ form.code.errors.0 }}</span>
                </div>
                <div class="col-xs-5">
                    <img id="image_code" src="/image/code/" style="width: 125px;">
                </div>
            </div>

        </div>
        <input type="submit" value="登 陆" class="btn btn-primary">
    </form>
</div>

</body>
</html>

5、类中添加code(生成验证码)

class LoginForm(BootStrapForm):
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,
        # 设置为必填属性
        required=True

    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),
        required=True
    )
    code = forms.CharField(
        label="验证码",
        widget=forms.TextInput,
        required=True
    )

    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)

6、显示验证码 

from io import BytesIO
from app01.utils.code import check_code


def image_code(request):
    # 调用pillow函数,生成图片
    img, code_string = check_code()

    # 写入自己的session中(以便以后进行校验)
    request.session['image_code'] = code_string

    # 给session设置60s超时
    request.session.set_expiry(60)
    # # 图片字母
    # print(code_string)
    # 新建一个内存,图片存入其中
    stream = BytesIO()
    img.save(stream, 'png')
    stream.getvalue()
    return HttpResponse(stream.getvalue())

7、进行校验

def login(request):
    # 有一条数据username=202117020035,password=202117020035的数据
    # passward=md5("202117020035")
    # models.Admin.objects.create(username="202117020035",password=passward)
    if request.method == "GET":
        form = LoginForm()
        return render(request, 'login.html', {"form": form})

    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 验证码的校验
        user_input_code = form.cleaned_data.pop('code')
        code = request.session.get('image_code', "")
        # 不区分大小写
        if code.upper() != user_input_code.upper():
            form.add_error("code", "验证码错误")
            return render(request, 'login.html', {'form': form})

        admain_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admain_object:
            # 在password字段下显示
            form.add_error("password", "用户名或密码错误")
            return render(request, 'login.html', {'form': form})
        # 用户名和密码都正确
        # 网站生成随机字符串;写到用户浏览器的cookie;在写入到session中
        request.session["info"] = {'id': admain_object.id, 'name': admain_object.username}

        # 七天免登录,session保存七天
        request.session.set_expiry(60*60*24*7)
        return redirect("/admain/list/")

    return render(request, 'login.html', {'form': form})

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值