【bbs02补】注册功能form组件-前端-后端-总结、登录功能(前端、后端、生成验证码)
1 注册功能
1.1 注册功能form组件
1.2 注册功能前端
1.3 注册功能后端
1.4 forms组件和前后端总结
2 登录功能
2.1 登录前端
2.2 生成验证码
1 注册功能
1.1 注册功能form组件
# 注册页面-用户名-密码-确认密码-邮箱-手机号-头像# form组件 可以帮助我们1 快速生成前端页面2 数据校验3 错误处理# 如何使用-1 写一个类,继承forms.Form-2 在类中写属性和方法-属性:要跟咱们要校验或自动生成页面的字段一一对应-方法:对字段进行校验:clean_字段名 给单个字段校验clean 给多个字段校验-3 在视图函数中使用-4 模板中使用# form表单中,如果定义了button或input 类型是"submit",只要点击,就会默认触发form表单的提交,如果我们又写了ajax提交,就会触发两次---》导致问题--把它搞外面-input 类型是"button"
from django import forms
from django.forms import widgets, ValidationError
from .models import UserInfoclass RegisterForm(forms.Form):# max_length=18 最长 18# min_length=3 最短 3# required=True 必填username = forms.CharField(max_length=18, min_length=3, required=True,label='用户名',error_messages={'required': '用户名字段必填','max_length': '长度不能超过18','min_length': '最短3'}, widget=widgets.TextInput(attrs={'class': 'form-control'}))password = forms.CharField(max_length=18, min_length=3, required=True,label='密码',error_messages={'required': '用户名字段必填','max_length': '长度不能超过18','min_length': '最短3'}, widget=widgets.PasswordInput(attrs={'class': 'form-control'}))re_password = forms.CharField(max_length=18, min_length=3, required=True,label='确认密码',error_messages={'required': '用户名字段必填','max_length': '长度不能超过18','min_length': '最短3'}, widget=widgets.PasswordInput(attrs={'class': 'form-control'}))email = forms.EmailField(max_length=18, min_length=3, required=True,label='邮箱',error_messages={'required': '用户名字段必填','max_length': '长度不能超过18','min_length': '最短3'}, widget=widgets.EmailInput(attrs={'class': 'form-control'}))phone = forms.CharField(max_length=11, min_length=11, required=True,label='手机号',error_messages={'required': '用户名字段必填','max_length': '长度不能超过11','min_length': '必须11为'}, widget=widgets.TextInput(attrs={'class': 'form-control'}))# 方法名只能写两类# 一类是 clean_字段名 校验单个字段def clean_username(self): # 如果能走到这里,说明上面的校验已经通过了,校验过后的数据都放在一个字典中---》cleaned_datausername = self.cleaned_data.get('username')# 用户名不能以sb开头if username.startswith('sb'):# 校验不通过,抛异常raise ValidationError('名字不能以sb开头')# 如果用户名存在,也不能注册了res = UserInfo.objects.filter(username=username).exists()if res:raise ValidationError('该用户已经存在')return username# 二类是 clean 同时校验多个字段def clean(self):password = self.cleaned_data.get('password')re_password = self.cleaned_data.get('re_password')if not password == re_password:raise ValidationError('两次密码不一致')return self.cleaned_data
1.2 注册功能前端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/static/js/jquery.min.js"></script><link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body><div class="container-fluid"><div class="row"><div class="col-md-6 col-md-offset-3"><h1 class="text-center">注册功能</h1><form id="register_form">{% csrf_token %}{% for foo in form %}<div class="form-group"><label for="{{ foo.auto_id }}">{{ foo.label }}</label>{{ foo }} <span class="pull-right error" style="color: red"></span></div>{% endfor %}<div class="form-group"><label for="id_avatar">头像<img src="/static/img/default.png" alt="" height="80px" width="80px" id="id_img"style="margin-left: 20px"></label><input type="file" id="id_avatar" class="form-control" accept="image/*" style="display: none"></div><div class="text-center"><input type="button" value="注册" class="btn btn-danger" id="id_submit"><span class="error" style="color: darkred;margin-left: 10px" id="id_error"></span></div></form></div></div>
</div></body><script>// 1 监控文件变化$('#id_avatar').change(function () {// 读出input 的图片,写到 img标签上// 需要借助于文件阅读器var fileReader = new FileReader();// 把文件对象读入文件阅读器中fileReader.readAsDataURL($('#id_avatar')[0].files[0])// 等文件读完,再放入fileReader.onload = function () {//$('#id_img').attr('height', '300px')$('#id_img').attr('src', fileReader.result)//$('#id_img')[0].src = fileReader.result}})// 2 按钮提交---》注册功能$('#id_submit').click(function () {var formdata = new FormData()// 把文件放入formdata.append('my_img', $('#id_avatar')[0].files[0])//放数据:用户名,密码,确认密码,手机号,邮箱 ,你可以一个个放--->笨办法/*formdata.append('username', $('#id_username').val())formdata.append('password', $('#id_password').val())formdata.append('re_password', $('#id_re_password').val())formdata.append('phone', $('#id_phone').val())formdata.append('email', $('#id_email').val())formdata.append('csrfmiddlewaretoken', '{{ csrf_token }}') // csrf 的token*/// 简单方案var register_form = $('#register_form').serializeArray() // 会把当前form表单中得数据放到列表套字典的形式/*数组[{name:xx,value:yy}, {…}, {…}, {…}, {…}]*///console.log(register_form)// jq 的循环$.each(register_form, function (i, v) {//console.log(v['name'])//console.log(v['value'])formdata.append(v['name'], v['value'])})$.ajax({url: '/register/',method: 'post',processData: false,contentType: false,data: formdata,success: function (data) {if (data.code == 100) {location.href = '/login/'} else { // 不成功// 两次密码不一致,把错误写在 注册按钮后面// input 自己的错误,写在自己后面// 循环返回的错误$.each(data.errors, function (key, value) {if (key == '__all__') {$('#id_error').html(value[0])}$('#id_' + key).next().html(value[0]).parent().addClass('has-error')})// 过3s后,清空错误,和红框setTimeout(function () {$('.error').html("").parent().removeClass('has-error')//alert('asfdsdaf')}, 3000)}}})})// 3 当用户名输入框失去焦点,我们就去后端校验用户名是否注册过$('#id_username').blur(function () {//alert('失去焦点了')//var username=$('#id_username').val()var username = $(this).val()$.ajax({url: '/check_username/?username=' + username,method: 'get',success: function (data) {console.log(data)if (data.code != 100) {// 1 清空输入框//$(this).val()// 2 错误提示//$(this).next().html(data.msg)console.log('ssss')// 两句可以并做一句---》链式调用// 如果在另一个内部函数中,就不能用this//var ss=$('#id_username').val()//$('#id_username').next().html(data.msg).parent().addClass('has-error').children('input').val("")$('#id_username').val('').next().html(data.msg).parent().addClass('has-error')}}})})</script>
</html>
1.3 注册功能后端
from django.shortcuts import render
from .forms import RegisterForm
from .models import UserInfo
from django.http import JsonResponsedef register(request):if request.method == 'GET':form = RegisterForm()return render(request, 'register.html', {'form': form})else:# # 1 数据# print(request.POST)# # 2 文件# print(request.FILES.get('my_img'))# 取出头像avatar = request.FILES.get('my_img')# 校验数据是否合法'''username: adminpassword: 123email: an@qq.comphone: 12345678935avatar:文件'''form = RegisterForm(request.POST) # 使用form校验传入的数据if form.is_valid(): # 校验通过# 保存data = form.cleaned_data# 把re_password 弹出data.pop('re_password')# 把头像加入if avatar:data['avatar'] = avatarUserInfo.objects.create_user(**data)return JsonResponse({'code': 100, 'msg': '注册成功'})else:return JsonResponse({'code': 101, 'msg': '注册失败', 'errors': form.errors})# 校验用户名是否存在的接口
def check_username(request):username = request.GET.get('username')res = UserInfo.objects.filter(username=username).exists()if res:# 约定状态码:100,表示成功,非100表示失败return JsonResponse({'code': 101, 'msg': '用户已经存在'})return JsonResponse({'code': 100, 'msg': '您可以注册'})
1.4 forms组件和前后端总结
# 1 forms组件-1 渲染模板-2 校验数据-3 渲染错误- form=RegisterForm()---渲染页面- form=RegisterForm(requets.POST)---校验数据
# 2 取数据,取文件-form-data提交数据-request.POST 中取数据-request.FILES.get('名字') 取文件-补:前端是key:value 后端变成了 key:[value]-request.data 不是真正的字典{'username': ['admin','xxx'], 'password': ['123']}request.POST.get('username')request.POST.getlist('username')# 3 保存 文件和数据# data 是form校验过后的数据,没有头像data.pop('re_password') # 不是表的字段# 把头像加入 头像是表的字段if avatar:data['avatar'] = avatar # 文件对象# avatar = models.ImageField(upload_to='avatar', default='avatar/default.png')内部自动:打开一个空文件,把文件写入到空文件中 【/media/avatar/】,并且把路径赋值给avatar数据库字段UserInfo.objects.create_user(**data)# 4 前端:头像实时显示-隐藏了 input file---》input只能接收图片类型-只要input发生变化(change)---》把图片读出来,写入到 img标签中var fileReader = new FileReader();fileReader.readAsDataURL($('#id_avatar')[0].files[0])fileReader.onload = function () {$('#id_img').attr('src', fileReader.result)}# 5 用户名失去焦点(blur)---》向后端校验# 6 form表单使用var register_form = $('#register_form').serializeArray() 转到数组中# 7 $.each(可以被循环的,function(){})# 8 错误信息渲染-__all__ 全局错误---》显示在注册后面if (key == '__all__') {$('#id_error').html(value[0])}-其他错误,显示在自己后面$('#id_' + key).next().html(value[0]).parent().addClass('has-error')-定时任务:3s后干什么setTimeout(function () {$('.error').html("").parent().removeClass('has-error')}, 3000)
2 登录功能
2.1 登录前端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/static/js/jquery.min.js"></script><link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body><div class="container-fluid"><div class="row"><div class="col-md-6 col-md-offset-3"><h1 class="text-center">登录功能</h1><form><div class="form-group"><label for="">用户名</label><input type="text" name="username" class="form-control"></div><div class="form-group"><label for="">密码</label><input type="text" name="password" class="form-control"></div><div class="form-group"><label for="">验证码</label><div class="row"><div class="col-md-6"><input type="text" name="code" class="form-control"></div><img src="/get_code/" alt="" class="col-md-6" height="35"></div></div><div class="text-center" style="margin-top: 50px"><input type="button" value="登录" class="btn btn-danger" id="id_submit"><span class="error" style="color: darkred;margin-left: 10px" id="id_error"></span></div></form></div></div>
</div></body></html>
2.2 生成验证码
# 第三方方案
https://pythonjishu.com/ljpdvvedzkqiovs/# 自己的方案
def get_code(request):# 前端显示图片 方式一# with open('./static/img/4.jpg', 'rb') as f:# data = f.read()# return HttpResponse(data)# 方式二:自己生成一张图片,保存到本地-->打开,返回给前端# image_tmp = Image.new('RGB', (300, 38), (255, 255, 0))## with open('code.png', 'wb') as f:# image_tmp.save(f, 'png')## with open('code.png', 'rb') as f:# data = f.read()# return HttpResponse(data)# 方式三:借助于ByteIo,把文件内容放在内存中# image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))# # 放在内存中# my_io = BytesIO()# image_tmp.save(my_io, 'png')# return HttpResponse(my_io.getvalue())# 方式四: 要在图片上写文字# image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))# # 把空图片放在了画板上# draw = ImageDraw.Draw(image_tmp)# draw.text((0, 0), 'lqz')# my_io = BytesIO()# image_tmp.save(my_io, 'png')# return HttpResponse(my_io.getvalue())# 方式5 :加入字体文件# image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))# # 把空图片放在了画板上# draw = ImageDraw.Draw(image_tmp)# # 加入字体# img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)# draw.text((0, 0), '西瓜大朗', fill=(0, 0, 128), font=img_font, )# my_io = BytesIO()# image_tmp.save(my_io, 'png')# return HttpResponse(my_io.getvalue())# 方式6 ,随机生成 5 大小写字母和数字,图片背景色和字的颜色每次不一样image_tmp = Image.new('RGB', (300, 38), (0, 255, 0))# 把空图片放在了画板上draw = ImageDraw.Draw(image_tmp)# 加入字体img_font = ImageFont.truetype('./static/font/xgdl.ttf', 23)draw.text((0, 0), '西瓜大朗', fill=(0, 0, 128), font=img_font, )my_io = BytesIO()image_tmp.save(my_io, 'png')return HttpResponse(my_io.getvalue())import randomdef get_random_code():code = ''for i in range(5):# 随机生成一个大写字母upper_char = chr(random.randint(65, 90))low_char = chr(random.randint(97, 122))num_char = str(random.randint(0, 9))res = random.choice([upper_char, low_char, num_char])code += resreturn codeif __name__ == '__main__':print(get_random_code())相关文章:
【bbs02补】注册功能form组件-前端-后端-总结、登录功能(前端、后端、生成验证码)
1 注册功能 1.1 注册功能form组件 1.2 注册功能前端 1.3 注册功能后端 1.4 forms组件和前后端总结 2 登录功能 2.1 登录前端 2.2 生成验证码 1 注册功能 1.1 注册功能form组件 # 注册页面-用户名-密码-确认密码-邮箱-手机号-头像# form组件 可以帮助我们1 快速生成前端页面2 数…...
MindSponge分子动力学模拟——定义一个分子系统
技术背景 在前面两篇文章中,我们分别介绍了分子动力学模拟软件MindSponge的软件架构和安装与使用。这里我们进入到实用化阶段,假定大家都已经在本地部署好了基于MindSpore的MindSponge的编程环境,开始用MindSponge去做一些真正的分子模拟的工…...
unity想让方法带一个默认参数怎么写
在C#中,包括Unity使用的C#版本,你可以为方法参数提供默认值。这允许你在调用方法时省略某些参数,并使用这些参数的默认值。以下是如何为一个方法参数设置默认值的示例: using UnityEngine; public class MyClass : MonoBehaviou…...
从零开始的软件测试学习之旅(六)测试网络基础知识
测试网络基础知识 HTTP和HTMLURLDNS客户端和服务器请求方法和状态码面试高频Fiddler抓包工具教学弱网 HTTP和HTML 概念 html: HyperText Markup Language 超文本标记语言 http: HyperText Transfer Protocol 超文本传输协议 超文本: 图片, 音频, 视频 关系:http 可以对 html 的…...
NSS题目练习
[SWPUCTF 2021 新生赛]gift_F12 通过题目提示可以知道flag应该可以在源代码中找到 查看源代码,直接用 ctrlf 搜索flag即可 [SWPUCTF 2021 新生赛]jicao 题目打开后能看到一串php代码,要求是用post传参传入idwllmNB以及用get传参传入json[x]"wllm&q…...
Springboot+vue项目零食销售商城
摘要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,零食销售商城当然也不能排除在外。零食销售商城是以实际运用为开发背景,运用软件工程原理和开发方法ÿ…...
cesium 雷达遮罩(电弧球效果)
cesium 雷达遮罩(电弧球效果) 以下为源码直接复制可用 1、实现思路 通过修改“material”材质来实现轨迹球效果 2、代码示例 2.1 index.html <!DOCTYPE html> <html lang="en"><head><!...
W801学习笔记二十三:语文和英语学习应用的代码汇总
前面几章,代码经过重构,可能有点乱。这里给个最终版本,以供参考。 1、应用基类: IScean.h enum SceanResult{SceanResult_EXIT 1, SceanResult_Done 2 };class IScean {public:IScean();virtual ~IScean();// 纯虚函数virtu…...
安卓LayoutParams浅析
目录 前言一、使用 LayoutParams 设置宽高二、不设置 LayoutParams2.1 TextView 的 LayoutParams2.2 LinearLayout 的 LayoutParams 三、getLayoutParams 的使用四、setLayoutParams 的作用五、使用 setWidth/setHeight 设置宽高 前言 先来看一个简单的布局,先用 x…...
UltralSO制作启动盘时报错:磁盘/映像容量太小解决办法
UltralSO制作启动盘时报错:磁盘/映像容量太小解决办法 发现网上随便下载的UltralSO制作启动盘时报错:磁盘/映像容量太小,导致制作启动盘出错 解决方案: 去这个地址下载:https://cn.ultraiso.net/xiazai.html 下载正版…...
2024-05-09四月初二周四
2024-05-09四月初二周四 06:40-23:00 深兰Ai第五期 Part1:课时258:00:00:00 12:30-13:00 午饭烧水: 13:30-23:00 机器学习 19:00-20:00 晚饭: 20:00-23:00 coding 2.5 特征降维 unending 23:00-06:30 烧水资料下载...
【微服务】springcloud整合dubbo3使用nacos作为注册中心
目录 一、前言 二、springboot版本升级带来的问题 2.1 springboot为什么需要升级版本...
php中常用的数据类型汇总
在 PHP 中,常用的数据类型主要有以下几种: 标量类型(Scalar Types) integer(整型):用于存储整数,可以是正数或负数。float(浮点型/双精度型):用于…...
【源码阅读】Golang中的go-sql-driver库源码探究
文章目录 前言一、go-sql-driver/mysql1、驱动注册:sql.Register2、驱动实现:MysqlDriver3、RegisterDialContext 二、总结 前言 在上篇文章中我们知道,database/sql只是提供了驱动相关的接口,并没有相关的具体实现,具…...
2024-05-08 postgres-火山模型-执行-记录
摘要: 2024-05-08 postgres-火山模型-执行-记录 上下文: 2024-05-08 postgres-调试及分析-记录-CSDN博客 火山模型: 数据流是在查询树上,自上而下进行拉取,由上而下的调用。树本身就表明了数据的流动。每次执行一个元组,也就类似于迭代器的…...
QT5带UI的常用控件
目录 新建工程,Qmainwindow带UI UI设计器 常用控件区 Buttons 按钮 containers 容器 控件属性区域 对象监视区 布局工具区 信号与槽区 简单例子1 放置一个按钮控件,改文本为发送,该按键为Button1; 按钮关联信号和…...
识货小程序逆向
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!wx a15018601872,x30184483x…...
【OceanBase 系列】—— OceanBase v4.3 特性解读:查询性能提升之利器列存储引擎
原文链接:OceanBase 社区 对于分析类查询,列存可以极大地提升查询性能,也是 OceanBase 做好 HTAP 和 OLAP 的一项不可缺少的特性。本文介绍 OceanBase 列存的实现特色。 OceanBase从诞生起就一直坚持LSM-Tree架构,不断打磨功能支…...
【Java开发的我出书啦,各位同仁快过来围观】!!!
文章目录 🔊博主介绍🥤本文内容出书的目的出书的过程书籍的内容 📥博主的话 🔊博主介绍 文章目录 🔊博主介绍🥤本文内容出书的目的出书的过程书籍的内容 📥博主的话 🌾阅读前&#x…...
AI预测福彩3D第10套算法实战化赚米验证第1弹2024年5月5日第1次测试
从今天开始,准备启用第10套算法,来验证下本算法的可行性。因为本算法通过近三十期的内测(内测版没有公开预测结果),发现本算法的预测结果优于其他所有算法的效果。彩票预测只有实战才能检验是否有效,只有真…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
