Django博客搭建_找回密码
Blog项目——找回密码
文章目录
- Blog项目——找回密码
- 一、 分析
- 二、步骤
- 三、代码
- 1. 前端
- 2. 后端——form
- 3. 后端——view
- 4. url
一、 分析
业务处理流程:
- 判断手机号是否为空,是否已注册
- 判断短信验证码是否为空,是否格式正确,是否与真实的短信验证码相同
- 判断密码是否为空,格式是否正确
- 判断确认密码与密码是否相同
请求方法:POST
url定义:/user/findpwd/
请求参数:url路径参数
参数 | 类型 | 前端是否必须传 | 描述 |
---|---|---|---|
password | 字符串 | 是 | 用户输入的密码 |
password_repeat | 字符串 | 是 | 用户输入的重复密码 |
mobile | 字符串 | 是 | 用户输入的手机号 |
sms_code | 字符串 | 是 | 用户输入的短信验证码 |
注:由于是post请求,在向后端发起请求时,需要附带csrf token
二、步骤
- 用户输入手机号(js判断是否为空,是否注册)
- 用户输入图形验证码
- 点击发送短信验证码(查看手机是否合法,验证码是否合法)
- 获取验证码,输入密码与重复密码,点击修改密码
- 获取每个值
- 判断每个值是否为空,是否合法
- 通过ajax往后台传json数据
- 后台接收数据
- 判断是否为空
- 将数据放入form表单进行数据清洗
- 如果数据正确,则将密码修改
- 如果不正确则返回错误信息
- 前台获取后台传来的响应码
- 如果是0,则重定向到登陆页面
- 如果不是0,则显示错误原因
三、代码
1. 前端
前端的代码与之前用户注册差不多,函数部分也是用到了类似的几个(拼接图片url,uuid,检查miobile是否注册,发送短信和修改密码)
接下来就来看看:
// @Auther:Summer
$(function () {let $img = $(".form-item .captcha-graph-img img"); // get imglet $mobile = $("#mobile");let $smsCodeBtn = $(".form-item .sms-captcha"); //get sms btnlet $mobileRetuenVal = ""; // this is run mobile_fun return vallet $findPwsBtn = $(".findpsw-btn");generate();$img.click(generate);$mobile.blur(function () {$mobileRetuenVal = fn_check_mobile();})// set make img funfunction generate() {imageUUID = generateUUID();let imageUrl = "/image_code/" + imageUUID +"/";$img.attr("src", imageUrl)}// the fun to create uuid_codefunction generateUUID() {let d = new Date().getTime();if (window.performance && typeof window.performance.now === "function") {d += performance.now(); //use high-precision timer if available}let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {let r = (d + Math.random() * 16) % 16 | 0;d = Math.floor(d / 16);return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);});return uuid;}// to check mobile whether registerfunction fn_check_mobile() {let sRetuenVal = "";let sMobile = $mobile.val(); // get mobile val// check mobile whether nullif(sMobile === ""){message.showError("手机号不能为空");return sRetuenVal;}// use re to check mobileif (!(/^1[3-9]\d{9}$/).test(sMobile)){message.showError("手机号格式错误,请重新输入");return sRetuenVal;}// send ajax$.ajax({url: "/mobiles/" + sMobile + "/",type: "GET",dataType: "json",async: false}).done(function (res) {if(res.data.count !== 1){message.showError("输入的手机号有误,请重新输入");}else{message.showSuccess("手机号输入正确");sRetuenVal = "success";}}).fail(function () {message.showError("服务器超时,请重试");})return sRetuenVal;}// send sms$smsCodeBtn.click(function () {// check moileif($mobileRetuenVal !== "success"){message.showError("请输入正确的手机号");return;}// get vallet text = $("#input_captcha").val();// check codeif(!text){message.showError("请输入验证码");return;}// check uuid of imgif(!imageUUID){message.showError("图片uuid码为空");return;}// set datalet sDataParm = {"mobile": $mobile.val(),"text": text,"image_code_id": imageUUID}// send ajax$.ajax({url: "/sms_code/",type: "POST",data: JSON.stringify(sDataParm),dataType: "json"}).done(function (res) {if(res.errno === "0"){message.showSuccess("短信验证码发送成功")$smsCodeBtn.attr('disabled',true);let num = 60;let t = setInterval(function () {if(num === 1){// 如果计时器到最后, 清除计时器对象clearInterval(t);$smsCodeBtn.attr('disabled',false);// 将点击获取验证码的按钮展示的文本恢复成原始文本$smsCodeBtn.html("重新发送验证码");}else {num -= 1;$smsCodeBtn.html(num + "秒");}},1000)}else{message.showError(res.errmsg);}}).fail(message.showError("服务器超时,请重试"))})// change psw$findPwsBtn.click(function (e) {// prevent default submite.preventDefault();// get all vallet sPassword = $("input[name=password]").val();let sPasswordRepeat = $("input[name=password_repeat]").val();let sMobile = $mobile.val();let sSmsCode = $("input[name=sms_captcha]").val();// check moileif($mobileRetuenVal !== "success"){message.showError("请输入正确的手机号");return;}// check passwordif((!sPassword) || (!sPasswordRepeat)){message.showError("密码与确认密码不能为空")return;}// check passwd lenif((sPassword.length < 6 || sPassword.length > 20) ||(sPasswordRepeat.length < 6 || sPasswordRepeat.length > 20)){message.showError("密码和确认密码的长度需在6-20位")return;}// check pass and pass_re whether sameif(sPassword !== sPasswordRepeat){message.showError("密码和确认密码不一致")return;}// check smscode lenif(!(/^\d{6}$/).test(sSmsCode)){message.showError("短信验证码格式不正确,必须是6位数字!")return;}// request// set request datalet SdataParams = {"password": sPassword,"password_repeat": sPasswordRepeat,"mobile": sMobile,"sms_code": sSmsCode};// send ajax$.ajax({url: "/user/findpwd/",type:"POST",data: JSON.stringify(SdataParams),// 请求内容的数据类型(前端发给后端的格式)contentType: "application/json; charset=utf-8",dataType: "json",}).done(function (res) {if(res.errno === "0"){message.showSuccess("修改密码成功");setTimeout(() =>{// redirect to login pagewindow.location.href = '/user/login/';},1500)}else{message.showError(res.errmsg);}}).fail(function () {message.showError("服务器超时,请重试")})})
});
注意,上面的代码原来是
$findPwsBtn.submit(function (e) {// prevent default submite.preventDefault();
这里变成了click,应为尝试了无数次,始终无法解开:
当使用submit的时候,无法接触默认操作,而只有在click的时候才能执行这个操作。如果有知道为什么会出现这样错误的,也欢迎留言区留下宝贵意见。
2. 后端——form
form用来进行数据清洗,主要的代码也与上次的form类似:
class ChangePswForm(forms.Form):password = forms.CharField(label="密码", max_length=20, min_length=6,error_messages={"max_length": "密码长度必须小于20位","min_length": "密码长度必须大于6位","required": "密码不能为空"})password_repeat = forms.CharField(label="确认密码", max_length=20, min_length=6,error_messages={"max_length": "密码长度必须小于20位","min_length": "密码长度必须大于6位","required": "密码不能为空"})mobile = forms.CharField(label="手机号", max_length=11, min_length=11,error_messages={"max_length": "手机号长度有误","min_length": "手机号长度有无","required": "手机号不能为空"})sms_code = forms.CharField(label="验证码", max_length=6, min_length=6,error_messages={"max_length": "验证码长度有误","min_length": "验证码长度有误","required": "验证码不能为空"})# 检查手机号是否存在def clean_mobile(self):tel = self.cleaned_data.get('mobile')if not Users.objects.filter(mobile=tel).exists():raise forms.ValidationError("手机号输入有误,请重新输入!")return teldef clean(self):cleaned_data = super().clean()passwd = cleaned_data.get('password')passwd_repeat = cleaned_data.get('password_repeat')if passwd != passwd_repeat:raise forms.ValidationError("两次密码不一致")# 校验短信验证码tel = cleaned_data.get('mobile')sms_text = cleaned_data.get('sms_code')# 建立redis连接redis_conn = get_redis_connection(alias='verify_codes')sms_fmt = "sms_{}".format(tel).encode('utf8')real_sms = redis_conn.get(sms_fmt)if (not real_sms) or (sms_text != real_sms.decode('utf-8')):raise forms.ValidationError("短信验证码错误")
3. 后端——view
view里需要注意的一个点就是,如果直接获取user实例,然后通过user.password=password是无法进行加密处理的,这里我使用了AbstractUser类自带的set_password函数
class FindPswView(View):def get(self, request):return render(request, 'users/findpsw.html')def post(self, request):json_data = request.bodyif not json_data:return to_json_data(errno=Code.PARAMERR, errmsg=[error_map[Code.PARAMERR]])data_dict = json.loads(json_data.decode("utf8"))form = ChangePswForm(data=data_dict)if form.is_valid():mobile = form.cleaned_data.get("mobile")password = form.cleaned_data.get("password")user = Users.objects.get(mobile=mobile)user.set_password(password)user.save()return to_json_data(errmsg="密码修改成功")else:error_map_list = []for item in form.errors.values():error_map_list.append(item)err_str = "/".join(error_map_list)return to_json_data(errno=Code.PARAMERR, errmsg=err_str)
更加别忘了,要保存!!!
4. url
# -*- coding: utf-8 -*-
# @Author : summer
from django.urls import path
from . import viewsapp_name = "user"urlpatterns = [path("login/", views.LoginView.as_view(), name="login"),path("register/", views.RegistarView.as_view(), name="register"),path("findpwd/", views.FindPswView.as_view(), name="findpwd"),
]
Django博客搭建_找回密码相关推荐
- Django博客搭建_用户注册1_图片生成
Blog项目--用户注册 文章目录 Blog项目--用户注册 一.设计接口思路 二.功能分析 三.图片验证码接口代码实现 1.图片验证码认证 2.后端视图实现 2-1 测试 2-2 升级 四.类视图 ...
- Django博客搭建_其他模块-文档下载
Blog项目--其他模块 文章目录 Blog项目--其他模块 一.分析 二.模型实现 三.路由注册 四.后端代码实现 视图部分 路由部分 五.前端代码实现 html部分 css部分 一.分析 业务处理 ...
- Django博客搭建-新闻模块6-新闻搜索功能(Django+Haystack+elasticsearch)
Blog项目--新闻模块 文章目录 Blog项目--新闻模块 一.需求分析 二.搜索引擎原理 三.Elasticsearch 特点 四.使用docker安装elasticsearch 五.后端代码实现 ...
- Django个人博客搭建4-配置使用 Bootstrap 4 改写模板文件
Django个人博客搭建1-创建Django项目和第一个App Django个人博客搭建2-编写文章Model模型,View视图 Django个人博客搭建3-创建superuser并向数据库中添加数据 ...
- Django个人博客搭建8-优化文章模块
Django个人博客搭建1-创建Django项目和第一个App Django个人博客搭建2-编写文章Model模型,View视图 Django个人博客搭建3-创建superuser并向数据库中添加数据 ...
- 用python搭建个人博客过程_手把手搭建个人博客(图文教程)
搭建个人博客 浏览体验更棒请移步原文:手把手搭建个人博客 首先我们谈一谈搭建个人博客必要性,个人认为在学习过程中,被动接受知识对你的提高是轻微的.比如你看网课学习,在听老师讲解的时候感觉简单易懂,代码 ...
- django orm级联_第 03 篇:创建 Django 博客的数据库模型
HelloGitHub-Team 成员--追梦人物 设计博客的数据库表结构 博客最主要的功能就是展示我们写的文章,它需要从某个地方获取博客文章数据才能把文章展示出来,通常来说这个地方就是数据库.我们把 ...
- python个人博客网站的搭建说明书_个人博客搭建线上实施方案
个人博客搭建线上实施方案 在hexo本地实施没有问题的基础上 实施方案 方案一:GithubPages 创建仓库, 仓库名为:.github.io 将本地Hexo博客推送到GithubPages 3. ...
- wordpress博客搭建-保姆教程
前言: 如今这个年代,估计每个人都有属于自己的服务器,放着也是放着,为什么不用来搭建一个博客呢. Wordpress作为目前流行的动态博客,至今已经发展了数十年,用wordpress建站简直是不能太简 ...
最新文章
- 《塞洛特傳說》道具系统
- c++缓冲区buffer
- codeforces 1016C - Vasya And The Mushrooms 【构造 + 思维】
- @ngrx入坑angular的schema,爽的一逼!
- 转载:百度地图api 常用 例子
- 「BZOJ1485」[HNOI2009] 有趣的数列 (卡特兰数列)
- python 颜色空间转换_python opencv入门 颜色空间转换(9)
- 图书馆占座系统(四)
- 华为服务器通过ilo虚拟光驱,如何通过ilo开启服务器远程桌面
- 介绍VMware虚拟化存储原理及数据恢复方法
- 双曲正切matlab,如何在MatLab中用双曲正切拟合数据点?
- 搜狗细胞词库解析(仅提取词和词频)
- SpaceSyntax【空间句法】之DepthMapX学习:第四篇 凸多边形图分析[未完]
- css 手型 没生效,css各种手型集合(css禁止手型)(示例代码)
- 高级Android开发年薪35万,2019安卓继续冲起来!
- 常见颜色RGB与数值对应表
- u大师u盘装系统win7_U盘启动联想ThinkPad E450 20DCA026CD重装win7系统教程分享
- 业务设计师(产品经理)P级晋升必备职能(P3-P7)
- Android进程保活的一般套路
- 【最小生成树】洛谷P2259 Charmer--viv