首页 > 其他分享 >【django学习-26】图片验证码

【django学习-26】图片验证码

时间:2024-05-15 20:31:32浏览次数:18  
标签:26 code return form randint random request 验证码 django

  • 1.我们在登录的时候,经常看到输入用户名、密码之外。还需要输入验证码。这个验证码是怎么实现的呢?
  • 2.前端
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/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>
        {% 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">
                    {{ 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>
  • 3.生成图片验证码,pip install pillow,使用第三方模块pillow
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter


def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

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


    def rndColor():
        """
        生成随机颜色
        :return:
        """
        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):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        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)

# if __name__ == "__main__":
#     img, code_str = check_code()
#     print(code_str)
#
#     with open('code.png', 'wb') as f:
#         img.save(f, format='png')
  • 4.访问登录界面时,会访问/image/code,执行视图函数image_code
def image_code(request):
    """生成图片验证码"""
    img,code_string = check_code()
    # print(code_string)

    # 写入到自己的session中(以便于后续获取验证码再进行校验)
    request.session['image_code'] = code_string
    # 给Session设置60s超时
    request.session.set_expiry(60)

    stream = BytesIO()
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())
  • 5.登录时,增加图片验证码的校验
from django.shortcuts import render, redirect,HttpResponse
from app01 import models
from app01.utils.bootstrap import BootStrapForm
from django import forms
from io import BytesIO
from app01.utils.encrypt import md5
from app01.utils.code import check_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      # 必填,默认为True
    )

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

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

def login(request):
    if request.method == "GET":
        form = LoginForm()
        return render(request,"login.html",{"form":form})
    form = LoginForm(data = request.POST)
    if form.is_valid():
        # print(form.cleaned_data)  # {'username': 'xwl', 'password': '1cd19cf980df7815e8303ab92ff66296'}
        # print(form.cleaned_data)  # {'username': 'xwl', 'password': '1cd19cf980df7815e8303ab92ff66296',"code":xxx}

        # 校验图片验证码
        user_input_code = form.cleaned_data.pop("code")   # 剔除图片,方便后面的用户密码校验
        code = request.session.get("image_code","")    # 获取生成的code
        # print(code)
        if code.upper() != user_input_code.upper():
            form.add_error("code","验证码错误")
            return render(request,"login.html",{"form":form})

        # 去数据库校验用户名和密码是否正确,获取用户对象、None
        # admin_object = models.Admin.objects.filter(username=xxx, password=xxx).first()
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            form.add_error("password", "用户名或密码错误")   # 主动在username字段显示错误信息
            # form.add_error("username", "用户名或密码错误")
            return render(request, 'login.html', {'form': form})

        # 用户名和密码正确
        # 网站生成随机字符串,写入浏览器的cookie中,再写入到session中
        request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
        # sesion可以保存7天
        request.session.set_expiry(60 * 60 * 24 * 7)
        return redirect('/admin/list/')

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

标签:26,code,return,form,randint,random,request,验证码,django
From: https://www.cnblogs.com/xwltest/p/18194636

相关文章

  • 【django学习-25】登录及使用中间件进行登录校验
    1.登录功能实现1.1:管理员表fromdjango.dbimportmodelsclassAdmin(models.Model):"""管理员"""username=models.CharField(verbose_name="用户名",max_length=32)password=models.CharField(verbose_name="密码......
  • 264 ugly number II 丑数
    问题描述Anuglynumberisapositiveintegerwhoseprimefactorsarelimitedto2,3,and5.Givenanintegern,returnthenth*uglynumber*.解释:一个丑数是一个正整数,其公因子只有2,3,5。给定数字n,求第n个丑数案例:Input:n=10Output:12Explanation:[1,2,......
  • django-drf 全局封装
    封装全局异常common_exceptions.pyfromrest_framework.viewsimportexception_handlerfromrest_framework.responseimportResponsedefcommon_exception_handler(exc,context):#记录日志request=context.get('request')view=context.get(�......
  • django中使用redis
    django中使用redis方式一:通用方式pool.pyimportredisPOOL=redis.ConnectionPool(max_connections=10,decode_responses=True)在哪里用,导入用即可fromutils.poolimportPOOLimportredisclassRedisView(ViewSet):deflist(self,request):conn=......
  • 实验26 使用bert构件词向量错误解决方案
    已经有源码没有报错,按步骤准备在terminal启动bert-serving-server,输入命令之后报错显示没有这样的命令:原先是按照网上的教程用:pipinstallbert-serving-server#serverpipinstallbert-serving-client#client,independentof`bert-serving-server`这俩命令安装了服......
  • 【django学习-24】自定义插件
    1.ModelForm可以帮助我们生成HTML标签,这种是普通的标签classUserModelForm(forms.ModelForm):classMeta:model=models.UserInfofields=["name","password",]form=UserModelForm()2.如果我们要使用bootstrap的标签,该怎么操作呢?2.1:自定义......
  • django启动时执行某个操作数据库的方法怎么实现
    为了让django启动时就执行某些方法做了如下尝试一、在Django中,可以通过AppConfig类的ready()方法来实现在Django启动时执行某个方法。首先,在你的应用的apps.py文件中,创建一个继承自AppConfig类的子类,并重写ready()方法。例如,假设你的应用名为myapp,则可以创建一个MyAppConfig类:......
  • Django RESTful API设计与实践指南
    title:DjangoRESTfulAPI设计与实践指南date:2024/5/1415:37:45updated:2024/5/1415:37:45categories:后端开发tags:DjangoRESTAPI设计版本控制安全认证性能优化部署策略实战项目第1章:Django基础知识1.1Django简介:Django是一个使用Python语言开发......
  • 【django学习-22】列表界面搜索功能
    1.需求:靓号列表界面,根据手机号码模糊匹配2.前端传search_data<divstyle="float:right;width:300px;"><formmethod="get"><divclass="input-group"><inputtype="text"name="q"clas......
  • 【django学习-21】ModelForm方式,自定义数据校验
    前言:我们在使用ModelForm新增数据时,除了使用默认的数据校验之外,还可以自定义数据校验例如:有个靓号的列表,新增/编辑校验1.代码示例1.1:modles.pyclassPrettyNum(models.Model):"""靓号表"""mobile=models.CharField(verbose_name="手机号",max_length=11)......