【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())

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

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

相关文章

Xamarin.Android项目显示Properties

在 Visual Studio 2022 中&#xff0c;如果您需要调出“Properties”&#xff08;属性&#xff09;窗口&#xff0c;您可以使用以下几种方法&#xff1a; 快捷键&#xff1a; 您可以按 F4 快速打开当前选择项的“Properties”窗口。

pytorch笔记:ReplicationPad1d

torch.nn.ReplicationPad1d(padding) 在 PyTorch 中&#xff0c;ReplicationPad1d 是一种用于一维数据的填充层该层通过复制序列的边缘值来增加数据的长度&#xff0c;这在卷积神经网络中常用于保持数据尺寸主要参数 padding 可以是一个整数或一个元组。 如果是一个整数&…

Python 植物大战僵尸

文章目录 效果图项目结构实现思路源代码 效果图 项目结构 实现思路 下面是代码的实现思路&#xff1a; 导入必要的库和模块&#xff1a;首先&#xff0c;我们导入了Python的os、time库以及pygame库&#xff0c;还有植物大战僵尸游戏中用到的各个植物和僵尸的类。 初始化游戏和…

从零开始学AI绘画,万字Stable Diffusion终极教程(一)

【第1期】SD入门 2022年8月&#xff0c;一款叫Stable Diffusion的AI绘画软件开源发布&#xff0c;从此开启了AIGC在图像上的爆火发展时期 率先学会SD的人&#xff0c;已经挖掘出了越来越多AI绘画有趣的玩法 从开始的AI美女、线稿上色、真人漫改、头像壁纸 到后来的AI创意字、AI…

Android性能优化面试题汇总

Android的性能优化涉及多个方面,如启动优化、稳定性优化、内存优化、网络优化、电量优化、安全优化等方面。 一、稳定性优化 1.1 你们做了哪些稳定性方面的优化 随着项目的逐渐成熟,用户基数逐渐增多,DAU持续升高,我们遇到了很多稳定性方面的问题,对于我们技术同学遇到…

如何在 Ubuntu 16.04 上使用 WireGuard 创建点对点 VPN

简介 WireGuard 是一种现代、高性能的 VPN&#xff0c;旨在提供易于使用的同时又具有强大的安全性。WireGuard 专注于在网络接口上使用公钥认证加密来提供安全连接。这意味着&#xff0c;与大多数 VPN 不同&#xff0c;它不强制执行拓扑结构&#xff0c;因此可以通过操纵周围的…

条件依赖性的方法示例

5个条件判断一件事情是否发生&#xff0c;每个条件可能性只有2种&#xff08;发生或者不发生&#xff09;&#xff0c;计算每个条件对这件事情发生的影响力&#xff0c;条件之间有很强的依赖关系。 例一 如果条件之间有很强的依赖关系&#xff0c;那么简单地计算每个条件独立的…

[论文阅读] 测试时间自适应TTA

最初接触 CVPR2024 TEA: Test-time Energy Adaptation [B站]&#xff08;1:35:00-1:53:00&#xff09;https://www.bilibili.com/video/BV1wx4y1v7Jb/?spm_id_from333.788&vd_source145b0308ef7fee4449f12e1adb7b9de2 实现&#xff1a; 读取预训练好的模型参数设计需要更…

Vue 组件通信

组件通信 组件与组件之间的数据传递 组件的数据是独立的&#xff0c;无法直接访问其他组件的数据。通过组件通信&#xff0c;可以访问其他组件的数据。 组件关系 父子关系非父子关系 组件通信解决方案 父子关系 父->子 父组件通过props将数据传递给子组件 App.vue …

蛋白质PDB文件解析+建图(biopython+DGL)

PDB文件解析 PDB文件设计得非常好&#xff0c;能够比较完整地记录实验测定数据 读懂蛋白质PDB文件-腾讯云开发者社区-腾讯云 (tencent.com) 科学网—PDB文件格式说明 - 李继存的博文 (sciencenet.cn) 从蛋白质结构来看&#xff0c;首先它会有多种不同的测定模型&#xff0c…

python学习笔记----面向对象(十)

一、什么是类 类是一个抽象的模板&#xff0c;用于创建具体的实例。可以将类理解为一个蓝图&#xff0c;它定义了一系列对象共有的属性&#xff08;数据&#xff09;和方法&#xff08;函数&#xff09;。类是对一组具有相同属性和功能的对象的抽象。例如&#xff0c;你可以定…

Jupyter Notebook魔术命令

Jupyter Notebook是一个基于网页的交互式笔记本&#xff0c;支持运行多种编程语言。 Jupyter Notebook 的本质式一个Web应用程序&#xff0c;便于创建和共享文学化程序文档&#xff0c;支持实现代码&#xff0c;数学方程&#xff0c;可视化和markdown。用途包括&#xff1a;数据…

2.6Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3-基础-Vue生命周期

在使用vue进行日常开发中&#xff0c;我们总有这样的需求&#xff0c;想在页面刚一加载出这个表格组件时&#xff0c;就发送请求去后台拉取 数据&#xff0c;亦或者想在组件加载前显示个loading图&#xff0c;当组件加载出来就让这个loading图消失等等这样或那样的需求。 要实…

【Python】模块和包

模块(Module)是一个python文件&#xff0c;能定义函数&#xff0c;类和变量&#xff0c;能包含可执行的代码。 一个模块就是一个工具包&#xff0c;里面有工具供我们使用&#xff0c;以实现功能。 类似于C语言的库函数 模块的导入 组合形式&#xff1a; import 模块名 fro…

Flutter笔记:Widgets Easier组件库(9)使用弹窗

Flutter笔记 Widgets Easier组件库&#xff08;9&#xff09;&#xff1a;使用弹窗 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

自定义拦截器jwt登录校验接口模拟账号登录

五一闲在宿舍&#xff0c;本来想写一个自己的简易博客网站&#xff0c;发现vue基础太差&#xff0c;做不出来页面效果于是便放弃&#xff0c;但也没有完全放弃。于是我分析了一下简易博客的后端实现流程&#xff0c;除了最基本的crud以外&#xff0c;在自己目前的对接口的分析中…

网络安全运维类面试非技术问题

1、你熟悉哪些品牌的安全设备 答&#xff1a;天融信的ngfw防火墙&#xff0c;老牌防火墙厂商&#xff0c;功能比较齐全&#xff0c;像流量检测&#xff0c;web应用防护和僵木蠕等模块都有&#xff0c;界面是红白配色&#xff0c;设计稍微有点老 2、IPS用的是哪个牌子的 答&…

Ubuntu启动后进入GRUB故障-Minimal BASH like line editing is supported.

目录 1.问题描述 2.解决方案 2.1 临时性办法 2.2 工具永久性修复 总结 1.问题描述 PC安装Ubuntu系统第二天重启后提示GUN GRUB version 2.04&#xff0c;之前是WindowsOS装Ubuntu后无法进入图形界面。具体原因据网友提供线索据说是由于在Windows上进行更新/重装/修改了引…

第Ⅰ章-V package.json文件详解

第Ⅰ章-Ⅰ 了解Vue3 创建一个Vue3项目 第Ⅰ章-Ⅱ Vue3自定义创建项目 项目文件详解 第Ⅰ章-III Vite 创建vue3 项目 第Ⅰ章-IV npm yarn pnpm 包管理器 第Ⅰ章-V package.json文件详解 简洁详解基本字段name 定义项目名称version 定义项目版本号description 对项目的简短描述m…

2024年 Java 面试八股文——Mybatis篇

目录 1. 什么是Mybatis&#xff1f; 2. 说说Mybatis的优缺点 3. Xml映射文件中&#xff0c;都有哪些标签 4. #{}和&{}有什么区别 5. Mybatis是如何进行分页的,分页插件的原理是什么 6. Mybatis是如何将sql执行结果封装为目标对象并返回的&#xff1f; 7. Mybatis是怎…