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.0from PIL import Image, ImageFont, ImageDraw
from random import choice,randintdef 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 = 15for 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_contentclass 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 BytesIOdef image_code(request):image, text = create_image_content()request.session["image_code"] = textrequest.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 = 15for 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"] = textrequest.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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PID算法入门

文章目录 122.12.22.3 344.14.24.3 1 e(t) 是偏差 实 和 目u(t) 是运算结果 2 层层叠加 得出完整的离散公式 2.1 kp 越大 系统偏差 减小的越快kp大的时候 会出现过冲现象&#xff1f; 0.5 那个会快他解释过冲 &#xff1a; 0.2的 5分钟正好到了 那0.5的五分钟 升的就比20多 就…

windows下WSL2 使用docker

问题一&#xff1a;WSL2中Systemctl命令不可用 curl -L -O “https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh” chmod x install.sh sudo ./install.sh install /opt/distrod/bin/distrod enable --start-on-windows-boot 问题二&#xff1a; 在…

④单细胞学习-cellchat细胞间通讯

目录 1&#xff0c;原理基础 流程 受体配体概念 方法比较 计算原理 2&#xff0c;数据 3&#xff0c;代码运行 1&#xff0c;原理基础 原文学习Inference and analysis of cell-cell communication using CellChat - PMC (nih.gov) GitHub - sqjin/CellChat: R toolk…

在 JavaScript 中实现数据加密与解密:Web Cryptography API 与 CryptoJS详解

在 JavaScript 中&#xff0c;可以使用 Web Cryptography API 或第三方库如 crypto-js 来实现加密和解密。本文将介绍如何使用这两种方法在客户端进行数据的加密和解密。 使用 Web Cryptography API Web Cryptography API 是现代浏览器提供的一个强大、原生的加密 API。它允许…

关于留痕的使用常见的问题

1. 登录微信 登录要导出数据的微信&#xff08;不支持微信多开&#xff0c;不支持部分老版本微信&#xff09; 相关信息 想把手机端的微信聊天记录转移到电脑上可以使用微信自带的聊天记录迁移功能 操作步骤&#xff1a; 安卓&#xff1a; 手机微信->我->设置->聊…

Python教程-快速入门基础必看课程07-判断结构

该视频主要讲述了Python中的布尔类型值和if-else语句。 布尔类型值是Python中的基本数据类型之一&#xff0c;只有两个值&#xff1a;True和False。它们常用于进行逻辑判断。 视频中详细介绍了如何定义和打印布尔类型值&#xff0c;以及如何进行比较和判断大小等操作。 if-els…

【做一道算一道】根据身高重建队列

根据身高重建队列 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 正好 有 ki 个身高大于或等于 hi 的人。 请你重新构造并返…

[深度学习]使用python部署yolov10的onnx模型

测试环境&#xff1a; onnxruntime1.15.1 opencv-python4.8.0.76 部分实现代码&#xff1a; parser argparse.ArgumentParser()parser.add_argument("--model", typestr, default"yolov10n.onnx", help"Input your ONNX model.")parser.add_arg…

leetcode hot100强化练习 0 - 35

Part I 哈希表 1. 两数之和 class Solution(object):def twoSum(self, nums, target):""":type nums: List[int]:type target: int:rtype: List[int]"""if not nums:return d {}for i, n in enumerate(nums):k target - nif k not in d:d[n]…

电子电器架构 --- 什么是域控制器?

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

美颜相机与美图秀秀的非会员图片保存技巧畅享专业级图像处理探索

美颜相机与美图秀秀的非会员图片保存技巧畅享专业级图像处理探索 今日对美颜相机和美图秀秀的深入使用中&#xff0c;我遇到了一些功能限制&#xff0c;特别是在尝试保存特定处理后的图片时&#xff0c;发现通常需要开通VIP会员才能享受完整服务。作为一名热衷于技术探索的爱好…

【数据结构】二叉树的层序遍历~动画超详解

目录 1 什么是层序遍历2 二叉树层序遍历的基本思路3 二叉树层序遍历的实现 1 什么是层序遍历 我们从字面意思就明白,所谓层序,就是一层一层按顺序去遍历一个二叉树,这和我们之前了解的按前中后序遍历方式完全不同 比方说这颗二叉树: 前序遍历: 层序遍历: 2 二叉树层序遍历的…

深度解析Go语言中的Slice切片

深度解析Go语言中的Slice切片 一、 简介二、数据结构三、初始化四、内容截取五、切片扩容六、元素删除七、切片拷贝 一、 简介 go中的切片&#xff0c;在某种程度上相当于别的语言中的“数组”。不同点在于切片的长度和容量是可变的&#xff0c;在使用过程中可以进行扩容。 二…

Android 使用kotlin Retrofit2 + Dagger2完成网络请求跟依赖注入组合使用

文章目录 &#xff08;一&#xff09;引入依赖&#xff08;二&#xff09;基本概念Dagger中的基本概念&#xff1a;Retrofit介绍 &#xff08;三&#xff09;Dagger2 Module 和 Provides 和 Component Inject&#xff08;四&#xff09;Retrofit2 创建数据类Bean跟Service服务&…

探索Java反射:解密动态性与灵活性

前言 Java反射是一项强大而灵活的技术&#xff0c;它使得程序能够在运行时获取类的信息、调用类的方法、访问类的字段等。本篇博客将深入探讨Java反射的原理、应用场景以及使用技巧&#xff0c;带你解密Java反射的奥秘。 什么是Java反射&#xff1f; 在传统的Java编程中&…

LabVIEW调用国产硬件DLL的稳定性问题及解决方案

在LabVIEW中调用国内公司提供的硬件DLL时&#xff0c;尽管可以运行&#xff0c;但常出现不稳定和bug问题&#xff0c;且厂家临时修改的版本未经长期测试。为确保稳定性和质量&#xff0c;需要制定系统化的测试和反馈机制、建立严格的版本控制、与厂家协作优化、并进行深入的自测…

C语言刷题(数组)

1. 编写程序利用数组实现将一个数插入到一个有序的数列中&#xff0c;要求插入后仍有序。 C语言代码 #include <stdio.h> int main(){ int n 0; printf("请输入有序数组元素的个数&#xff1a;\n"); scanf("%d",&n); //定义并输入数组 …

3. MySQL 数据表的基本操作

文章目录 【 1. MySQL 创建数据表 】【 2. MySQL 查看表 】2.1 查看表的属性DESCRIBE/DESC 以表格的形式展示表属性SHOW CREATE TABLE 以SQL语句的形式展示表属性 2.2 查看表的内容 【 3. MySQL 修改数据表结构 】3.1 修改表名3.2 修改表字符集3.3 添加字段在末尾添加字段在开头…

LLMs Can’t Plan, But Can Help Planning in LLM-Modulo Frameworks

更多精彩内容&#xff0c;请关注微信公众号&#xff1a;NLP分享汇 原文链接&#xff1a;LLMs Can’t Plan, But Can Help Planning in LLM-Modulo Frameworks 你是怎么理解LLM的规划和推理能力呢&#xff0c;来自亚利桑那州立大学最近的一篇论文&#xff0c;对LLM的规划、推理…

RESTful API开发:Flask库设计用户认证接口的6个要点

在当今的Web开发世界里&#xff0c;RESTful API已然成为应用程序间数据交互的标准方式。它们简洁、灵活&#xff0c;使得前后端分离更加顺畅。而Flask&#xff0c;作为一款轻量级且功能强大的Python Web框架&#xff0c;无疑是构建RESTful API的理想工具。然而&#xff0c;要确…