Blog项目——找回密码

文章目录

  • Blog项目——找回密码
    • 一、 分析
    • 二、步骤
    • 三、代码
      • 1. 前端
      • 2. 后端——form
      • 3. 后端——view
      • 4. url

一、 分析

业务处理流程:

  • 判断手机号是否为空,是否已注册
  • 判断短信验证码是否为空,是否格式正确,是否与真实的短信验证码相同
  • 判断密码是否为空,格式是否正确
  • 判断确认密码与密码是否相同

请求方法POST

url定义/user/findpwd/

请求参数:url路径参数

参数 类型 前端是否必须传 描述
password 字符串 用户输入的密码
password_repeat 字符串 用户输入的重复密码
mobile 字符串 用户输入的手机号
sms_code 字符串 用户输入的短信验证码

注:由于是post请求,在向后端发起请求时,需要附带csrf token

二、步骤

  1. 用户输入手机号(js判断是否为空,是否注册)
  2. 用户输入图形验证码
  3. 点击发送短信验证码(查看手机是否合法,验证码是否合法)
  4. 获取验证码,输入密码与重复密码,点击修改密码
  5. 获取每个值
  6. 判断每个值是否为空,是否合法
  7. 通过ajax往后台传json数据
  8. 后台接收数据
    1. 判断是否为空
    2. 将数据放入form表单进行数据清洗
    3. 如果数据正确,则将密码修改
    4. 如果不正确则返回错误信息
  9. 前台获取后台传来的响应码
    1. 如果是0,则重定向到登陆页面
    2. 如果不是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博客搭建_找回密码相关推荐

  1. Django博客搭建_用户注册1_图片生成

    Blog项目--用户注册 文章目录 Blog项目--用户注册 一.设计接口思路 二.功能分析 三.图片验证码接口代码实现 1.图片验证码认证 2.后端视图实现 2-1 测试 2-2 升级 四.类视图 ...

  2. Django博客搭建_其他模块-文档下载

    Blog项目--其他模块 文章目录 Blog项目--其他模块 一.分析 二.模型实现 三.路由注册 四.后端代码实现 视图部分 路由部分 五.前端代码实现 html部分 css部分 一.分析 业务处理 ...

  3. Django博客搭建-新闻模块6-新闻搜索功能(Django+Haystack+elasticsearch)

    Blog项目--新闻模块 文章目录 Blog项目--新闻模块 一.需求分析 二.搜索引擎原理 三.Elasticsearch 特点 四.使用docker安装elasticsearch 五.后端代码实现 ...

  4. Django个人博客搭建4-配置使用 Bootstrap 4 改写模板文件

    Django个人博客搭建1-创建Django项目和第一个App Django个人博客搭建2-编写文章Model模型,View视图 Django个人博客搭建3-创建superuser并向数据库中添加数据 ...

  5. Django个人博客搭建8-优化文章模块

    Django个人博客搭建1-创建Django项目和第一个App Django个人博客搭建2-编写文章Model模型,View视图 Django个人博客搭建3-创建superuser并向数据库中添加数据 ...

  6. 用python搭建个人博客过程_手把手搭建个人博客(图文教程)

    搭建个人博客 浏览体验更棒请移步原文:手把手搭建个人博客 首先我们谈一谈搭建个人博客必要性,个人认为在学习过程中,被动接受知识对你的提高是轻微的.比如你看网课学习,在听老师讲解的时候感觉简单易懂,代码 ...

  7. django orm级联_第 03 篇:创建 Django 博客的数据库模型

    HelloGitHub-Team 成员--追梦人物 设计博客的数据库表结构 博客最主要的功能就是展示我们写的文章,它需要从某个地方获取博客文章数据才能把文章展示出来,通常来说这个地方就是数据库.我们把 ...

  8. python个人博客网站的搭建说明书_个人博客搭建线上实施方案

    个人博客搭建线上实施方案 在hexo本地实施没有问题的基础上 实施方案 方案一:GithubPages 创建仓库, 仓库名为:.github.io 将本地Hexo博客推送到GithubPages 3. ...

  9. wordpress博客搭建-保姆教程

    前言: 如今这个年代,估计每个人都有属于自己的服务器,放着也是放着,为什么不用来搭建一个博客呢. Wordpress作为目前流行的动态博客,至今已经发展了数十年,用wordpress建站简直是不能太简 ...

最新文章

  1. 《塞洛特傳說》道具系统
  2. c++缓冲区buffer
  3. codeforces 1016C - Vasya And The Mushrooms 【构造 + 思维】
  4. @ngrx入坑angular的schema,爽的一逼!
  5. 转载:百度地图api 常用 例子
  6. 「BZOJ1485」[HNOI2009] 有趣的数列 (卡特兰数列)
  7. python 颜色空间转换_python opencv入门 颜色空间转换(9)
  8. 图书馆占座系统(四)
  9. 华为服务器通过ilo虚拟光驱,如何通过ilo开启服务器远程桌面
  10. 介绍VMware虚拟化存储原理及数据恢复方法
  11. 双曲正切matlab,如何在MatLab中用双曲正切拟合数据点?
  12. 搜狗细胞词库解析(仅提取词和词频)
  13. SpaceSyntax【空间句法】之DepthMapX学习:第四篇 凸多边形图分析[未完]
  14. css 手型 没生效,css各种手型集合(css禁止手型)(示例代码)
  15. 高级Android开发年薪35万,2019安卓继续冲起来!
  16. 常见颜色RGB与数值对应表
  17. u大师u盘装系统win7_U盘启动联想ThinkPad E450 20DCA026CD重装win7系统教程分享
  18. 业务设计师(产品经理)P级晋升必备职能(P3-P7)
  19. Android进程保活的一般套路
  20. 【最小生成树】洛谷P2259 Charmer--viv

热门文章

  1. 计算机网络 -广域网WAN (PPP协议和HDLC协议)
  2. mybatis异步操作数据库
  3. 儿童书写台灯哪个牌子比较好?盘点儿童护眼灯合格的品牌
  4. 解决AD导入dxf文件时报some entities were discarded during import?的问题
  5. 字符串中的十六进制字符如何转换成十六进制数
  6. 众昂矿业:新能源新材料产业链对萤石需求大增
  7. 快手极速版——青龙脚本
  8. 有没有免费word转pdf不限制页数的?
  9. VSCode调试单片机
  10. doc类型文件中的图片批量加水印