9-Django项目--验证码操作

目录

templates/login/login.html

utils/code.py

views/login.py

验证码

生成验证码

code.py

应用验证码

views.py

login.html


templates/login/login.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.css'%}">
</head>
<body>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html {
            height: 100%;
        }
        body {
            height: 100%;
        }
        .container {
            height: 100%;
            width: 100%;
            background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
        }
        .login-wrapper {
            background-color: #fff;
            width: 358px;
            height: 588px;
            border-radius: 15px;
            padding: 0 50px;
            position: relative;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
        .header {
            font-size: 38px;
            font-weight: bold;
            text-align: center;
            line-height: 200px;
        }
        .input-item {
            display: block;
            width: 100%;
            margin-bottom: 20px;
            border: 0;
            padding: 10px;
            border-bottom: 1px solid rgb(128, 125, 125);
            font-size: 15px;
            outline: none;
        }
        .input-item:placeholder {
            text-transform: uppercase;
        }
        .btn {
            text-align: center;
            padding: 10px;
            width: 100%;
            margin-top: 40px;
            background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
            color: #fff;
        }
        .msg {
            text-align: center;
            line-height: 88px;
        }
        a {
            text-decoration-line: none;
            color: #abc1ee;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="login-wrapper">
            <div class="header">Login</div>
            <div class="form-wrapper">
                <form method="post" novalidate>
                    {% csrf_token %}
                    <div class="col-md-12">
                        {{ form.username }}
                        <span style="color: red">{{ form.password.errors.0 }}</span>
                        {{ form.password }}
                    </div>
                    <div class="col-md-7">
                        {{ form.code }}
                        <span style="color:red;">{{ form.code.errors.0 }}</span>
                    </div>
                    <div class="col-md-5">
                        <button style="border: none">
                            <img src="/image/code/">
                        </button>

                    </div>

                    <button class="btn" type="submit">Login</button>
                </form>
            </div>

        </div>
    </div>
</body>
</html>

</body>
</html>

utils/code.py

# -*- coding:utf-8 -*-
# pip install pillow==9.4.0

from PIL import Image, ImageFont, ImageDraw
from random import choice,randint

def create_image_content():
    # 创建一张图片
    img = Image.new(mode="RGB", size=(110, 40), color=(255, 255, 255))
    # 创建一个画笔
    draw = ImageDraw.Draw(img, mode="RGB")
    font = ImageFont.truetype("./simkai.ttf", size=30)

    # 验证码出现的字符
    text = "ABCDEFG23456789"

    # 存放四位验证码的字符串
    image_text = ""
    # 生成几位数的验证码,就循环几次
    for num in range(4):
        image_text += choice(text)

    # 每次遍历的时候,将字符添加到图片上
    x = 15
    for i in image_text:
        # 为每一位验证码添加不同颜色
        R = str(randint(0, 255))
        G = str(randint(0, 255))
        B = str(randint(0, 255))
        draw.text(
            (x, 5),
            text=i,
            font=font,
            fill=f"rgb({R},{G},{B})"
        )
        x += 20

    # 添加干扰线条
    for i in range(1, randint(3, 6)):
        x1, y1 = randint(0, 110), randint(0, 40)
        x2, y2 = randint(0, 110), randint(0, 40)
        R = str(randint(0, 255))
        G = str(randint(0, 255))
        B = str(randint(0, 255))
        draw.line((x1, y1, x2, y2),fill=f"rgb({R},{G},{B})", width=2)

    # 添加干扰点
    for i in range(1, randint(30, 50)):
        x1, y1 = randint(0, 110), randint(0, 40)
        R = str(randint(0, 255))
        G = str(randint(0, 255))
        B = str(randint(0, 255))
        draw.point([x1, y1], fill=f"rgb({R},{G},{B})")

    # print(image_text)
    # img.save("code.png")
    # print(img)
    return [img, image_text]



views/login.py

# -*- coding:utf-8 -*-
from django.shortcuts import render, redirect,HttpResponse
from demo_one.utils import pwd_data
from django import forms
from demo_one import models
from demo_one.utils.code import create_image_content


class LoginForm(forms.Form):
    username = forms.CharField(label="用户名", widget=forms.TextInput(
        attrs={"class": "input-item", "autocomplete": "off", "placeholder": "请输入用户名"}))
    password = forms.CharField(label="密码", widget=forms.PasswordInput(
        attrs={"class": "input-item", "autocomplete": "off", "placeholder": "请输入密码"}))
    code = forms.CharField(label="验证码", widget=forms.TextInput(
        attrs={"class": "input-item", "autocomplete": "off", "placeholder": "请输入验证码"}))


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


def login(request):
    if request.method == "GET":
        form = LoginForm()
        return render(request, "login/login.html", {"form": form})

    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 去数据库进行校验
        # print(form.cleaned_data)
        # 使用pop删除,pop返回被删除的值
        user_input_code = form.cleaned_data.pop("code")
        code = str(request.session.get("image_code"))
        # print("我自己输入的是:", user_input_code)
        # print("系统生成的是:", code)
        if user_input_code.upper() != code.upper():
            form.add_error("code", "验证码错误")
            return render(request, "login/login.html", {"form": form})
        admin_object = models.Adminrole.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            # 给输入框添加一个错误提示
            form.add_error("password", "用户名或密码错误")
            return render(request, "login/login.html", {"form": form})
        # 登录成功之后
        # 将登录信息存储在session当中
        request.session["info"] = {"id": admin_object.id, "username": admin_object.username,
                                   "password": admin_object.password, "role": admin_object.role}
        # 时效性
        request.session.set_expiry(60 * 60 * 24 * 30)
        # 登录成功后跳转到首页
        return redirect("/")
    return render(request, "login/login.html", {"form": form})


def logout(request):
    request.session.clear()
    return redirect("/login/")


from io import BytesIO

def image_code(request):
    image, text = create_image_content()
    request.session["image_code"] = text
    request.session.set_expiry(60)

    stream = BytesIO()
    image.save(stream, "png")
    return HttpResponse(stream.getvalue())

验证码

生成验证码

  • code.py

    # -*- coding:utf-8 -*-
    # pip install pillow==9.4.0
    ​
    from PIL import Image, ImageFont, ImageDraw
    from random import choice,randint
    ​
    def create_image_content():
        # 创建一张图片
        img = Image.new(mode="RGB", size=(110, 40), color=(255, 255, 255))
        # 创建一个画笔
        draw = ImageDraw.Draw(img, mode="RGB")
        font = ImageFont.truetype("./simkai.ttf", size=30)
    ​
        # 验证码出现的字符
        text = "ABCDEFG23456789"
    ​
        # 存放四位验证码的字符串
        image_text = ""
        # 生成几位数的验证码,就循环几次
        for num in range(4):
            image_text += choice(text)
    ​
        # 每次遍历的时候,将字符添加到图片上
        x = 15
        for i in image_text:
            # 为每一位验证码添加不同颜色
            R = str(randint(0, 255))
            G = str(randint(0, 255))
            B = str(randint(0, 255))
            draw.text(
                (x, 5),
                text=i,
                font=font,
                fill=f"rgb({R},{G},{B})"
            )
            x += 20
    ​
        # 添加干扰线条
        for i in range(1, randint(3, 6)):
            x1, y1 = randint(0, 110), randint(0, 40)
            x2, y2 = randint(0, 110), randint(0, 40)
            R = str(randint(0, 255))
            G = str(randint(0, 255))
            B = str(randint(0, 255))
            draw.line((x1, y1, x2, y2),fill=f"rgb({R},{G},{B})", width=2)
    ​
        # 添加干扰点
        for i in range(1, randint(30, 50)):
            x1, y1 = randint(0, 110), randint(0, 40)
            R = str(randint(0, 255))
            G = str(randint(0, 255))
            B = str(randint(0, 255))
            draw.point([x1, y1], fill=f"rgb({R},{G},{B})")
    ​
        # print(image_text)
        # img.save("code.png")
        # print(img)
        return [img, image_text]

应用验证码

  • views.py

    def login(request):
        if request.method == "GET":
            form = LoginForm()
            return render(request, "login/login.html", {"form": form})
    ​
        form = LoginForm(data=request.POST)
        if form.is_valid():
            # 去数据库进行校验
            # print(form.cleaned_data)
            # 使用pop删除,pop返回被删除的值
            user_input_code = form.cleaned_data.pop("code")
            code = str(request.session.get("image_code"))
            # print("我自己输入的是:", user_input_code)
            # print("系统生成的是:", code)
            if user_input_code.upper() != code.upper():
                form.add_error("code", "验证码错误")
                return render(request, "login/login.html", {"form": form})
            admin_object = models.Adminrole.objects.filter(**form.cleaned_data).first()
            if not admin_object:
                # 给输入框添加一个错误提示
                form.add_error("password", "用户名或密码错误")
                return render(request, "login/login.html", {"form": form})
            # 登录成功之后
            # 将登录信息存储在session当中
            request.session["info"] = {"id": admin_object.id, "username": admin_object.username,
                                       "password": admin_object.password, "role": admin_object.role}
            # 时效性
            request.session.set_expiry(60 * 60 * 24 * 30)
            # 登录成功后跳转到首页
            return redirect("/")
        return render(request, "login/login.html", {"form": form})
    ​
    ​
    def logout(request):
        request.session.clear()
        return redirect("/login/")
    ​
    ​
    from io import BytesIO
    ​
    def image_code(request):
        image, text = create_image_content()
        request.session["image_code"] = text
        request.session.set_expiry(60)
    ​
        stream = BytesIO()
        image.save(stream, "png")
        return HttpResponse(stream.getvalue())

login.html

  • login.html
    
    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="{% static 'css/bootstrap.css'%}">
    </head>
    <body>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            html {
                height: 100%;
            }
            body {
                height: 100%;
            }
            .container {
                height: 100%;
                width: 100%;
                background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
            }
            .login-wrapper {
                background-color: #fff;
                width: 358px;
                height: 588px;
                border-radius: 15px;
                padding: 0 50px;
                position: relative;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
            }
            .header {
                font-size: 38px;
                font-weight: bold;
                text-align: center;
                line-height: 200px;
            }
            .input-item {
                display: block;
                width: 100%;
                margin-bottom: 20px;
                border: 0;
                padding: 10px;
                border-bottom: 1px solid rgb(128, 125, 125);
                font-size: 15px;
                outline: none;
            }
            .input-item:placeholder {
                text-transform: uppercase;
            }
            .btn {
                text-align: center;
                padding: 10px;
                width: 100%;
                margin-top: 40px;
                background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
                color: #fff;
            }
            .msg {
                text-align: center;
                line-height: 88px;
            }
            a {
                text-decoration-line: none;
                color: #abc1ee;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="login-wrapper">
                <div class="header">Login</div>
                <div class="form-wrapper">
                    <form method="post" novalidate>
                        {% csrf_token %}
                        <div class="col-md-12">
                            {{ form.username }}
                            <span style="color: red">{{ form.password.errors.0 }}</span>
                            {{ form.password }}
                        </div>
                        <div class="col-md-7">
                            {{ form.code }}
                            <span style="color:red;">{{ form.code.errors.0 }}</span>
                        </div>
                        <div class="col-md-5">
                            <button style="border: none">
                                <img src="/image/code/">
                            </button>
    ​
                        </div>
    ​
                        <button class="btn" type="submit">Login</button>
                    </form>
                </div>
    ​
            </div>
        </div>
    </body>
    </html>
    ​
    </body>
    </html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/671680.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Polar Web【简单】login

Polar Web【简单】login 本文旨在记录此题的探索和解决过程。 Contents Polar Web【简单】login探索&思路EXP (python)结果&总结 探索&思路 查看源码&#xff0c;发现存在用户信息泄露。尝试用获取信息登录&#xff0c;显示成功&#xff0c;但其后没有可做的操作。…

【力扣】不相交的线

一、题目描述 二、题目解析 根据上图及题目给出的示例&#xff0c;我们不难发现&#xff0c;我们其实要找的就是两个数组中的最长公共子序列的长度。 因此&#xff0c;本题我们就可以直接转化为求两个数组中的最长公共子序列的长度。 对于 最长公共子序列问题&#xff0c;可…

Java Socket 网络编程实例(阻塞IO、非阻塞IO、多路复用Selector、AIO)

文章目录 1. 概述2. TCP 阻塞式IO 网络编程实例2.1 TCP网络编程服务端2.2 ByteBufferUtil2.3 客户端代码2.4 运行截图 3. TCP 非阻塞式IO 网络编程实例3.1 服务端3.2 客户端3.3 运行截图 4. 多路复用4.1 服务器端4.2 客户端4.3 运行截图 5. AIO5.1 AIO 服务端5.2 客户端5.3 运行…

【Python】Python异步编程

Python 异步编程 异步编程 异步编程是一种编程范式&#xff0c;通过非阻塞的方式执行任务&#xff0c;允许程序在等待某些操作&#xff08;如I/O操作、网络请求、数据库查询等&#xff09;完成时&#xff0c;继续执行其他任务。这与同步编程&#xff08;或阻塞编程&#xff09…

【图像处理与机器视觉】XJTU期末考点

题型 选择&#xff1a;1 分10 填空&#xff1a;1 分15 简答题&#xff08;也含有计算和画图&#xff09;&#xff1a;10 分*4 计算题&#xff1a;15 分20 分 考点 选择题&#xff08;部分&#xff09; 数字图像处理基础 p(x,y),q(s,t)两个像素之间的距离由公式&#xff1a…

知乎x-zse-96、x-zse-81

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

GraphQL(2):使用express和GraphQL编写helloworld

1 安装express、graphql以及express-graphql 在项目的目录下运行一下命令。 npm init -y npm install express graphql express-graphql -S 2 新建helloworld.js 代码如下&#xff1a; const express require(express); const {buildSchema} require(graphql); const grap…

spring mvc 中怎样定位到请求调用的controller

前言 在java web开发过程中&#xff0c;正常情况下controller都是我们自己写的&#xff0c;我们可以很方便的定位到controller的位置。但是有些时候我们引入的其他依赖中可能也有controller&#xff0c;为了找到并方便的调试jar包中的controller&#xff0c;我们一般会进行全局…

基于Java的零食管理系统的设计与实现(论文+源码)_kaic

摘 要 随着科技的进步&#xff0c;以及网络的普及&#xff0c;都为人们的生活提供了极大的方便。因此&#xff0c;在管理”三姆”宿舍在线零食商店时&#xff0c;与现代的网络联系起来是非常必要的&#xff0c;本次设计的系统在研发过程中应用到了Java技术&#xff0c;这在一定…

windows10系统64位安装delphiXE11.2完整教程

windows10系统64位安装delphiXE11.2完整教程 https://altd.embarcadero.com/download/radstudio/11.0/radstudio_11_106491a.iso XE11.1 https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso XE11.2 关键使用文件在以下内容&#xff1a;windows10…

现代信号处理12_谱估计的4种方法(CSDN_20240602)

Slepian Spectral Estimator(1950) 做谱估计的目标是尽可能看清楚信号功率谱在某一个频率上的情况&#xff0c;假设我们想了解零频时的分布&#xff0c;最理想的情况是滤波器的传递函数H(ω) 是一个冲激函数&#xff0c;这样就没有旁瓣&#xff0c;也就没有泄漏&#xff1b;其次…

回溯算法 -- 216. 组合总和 III

目录 一.题目描述 二.解题思路 三.回溯三部曲 3.1确定递归函数的参数 3.2确认递归的终止条件 3.3确定单层循环逻辑 四.具体的代码 一.题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返…

经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)

给你一个由 正 整数组成的数组 nums 。 如果数组中的某个子数组满足下述条件&#xff0c;则称之为 完全子数组 &#xff1a; 子数组中 不同 元素的数目等于整个数组不同元素的数目。 返回数组中 完全子数组 的数目。 子数组 是数组中的一个连续非空序列。 示例 1&#xff1…

【1】AI介绍

迎接 AGI 时代 AGI(Artificial General Intelligence),人工通用智能,AGI是一种可以执行复杂任务的人工智能,能够完全模仿人类智能的行为。应用领域涉及医疗、交通、智能家居等多个与人类活动密切相关的领域。 AGI 多久会到来? 乐观预测:明年(未来已来)主流预测:3-5…

【云原生】Docker Compose 使用详解

目录 一、前言 二、Docker Compose 介绍 2.1 Docker Compose概述 2.2 Docker Compose特点 2.3 Docker Compose使用场景 三、Docker Compose 搭建 3.1 安装docker环境 3.2 Docker Compose安装方式一 3.2.1 下载最新版/如果不是最新可替换最新版本 3.2.2 设置权限 3.2.…

Zigbee +PC上位机 无线控制二维云台开发笔记

今日尝试开发一款简单好学的PC上位机无线控制二维云台的小试验品&#xff1a; 主要开发环境与工具介绍&#xff1a; 单片机 STM32F103C8T6 使用标准库函数编程 Visual Studio 2022软件C# Winform 开发 上位机控制软件 DL_20 无线串口模块 &#xff0b; USB-TTL 模块 实现无线通…

使用 Scapy 库编写 Ping of Death 攻击脚本

一、介绍 1.1 概述 Ping of Death&#xff08;PoD&#xff09;攻击是一种历史悠久的拒绝服务&#xff08;DoS&#xff09;攻击&#xff0c;攻击者通过发送特制的畸形ICMP Echo请求数据包&#xff0c;导致目标系统无法正确处理&#xff0c;从而导致系统崩溃、重启或无法响应正…

用于相似图片搜索引擎的Python OpenCV图像直方图

图像直方图 那么&#xff0c;图像直方图到底是什么&#xff1f; 图片 图像的构成是由像素点构成的&#xff0c;每个像素点的值代表着该点的颜色&#xff08;灰度图或者彩色图&#xff09;。所谓直方图就是对图像的中的这些像素点的值进行统计&#xff0c;得到一个统一的整体的…

手眼标定学习笔记

目录 标定代码&#xff1a; 手眼标定原理学习 什么是手眼标定 手眼标定的目的 eye in hand eye to hand AXXB问题的求解 标定代码&#xff1a; GitHub - pumpkin-ws/HandEyeCalib 推荐博文&#xff1a; https://zhuanlan.zhihu.com/p/486592374 手眼标定原理学习 参…

YOLOv8: 标注石头、识别边缘及计算面积的方案

YOLOv8: 标注石头、识别边缘及计算面积的方案 引言 YOLO&#xff08;You Only Look Once&#xff09;是一种非常有效的实时目标检测算法&#xff0c;自其首次发布以来就受到了广泛的关注和应用。YOLOv8 是这一系列算法的最新版本&#xff0c;继承了之前版本的高效性和准确性&a…