用户相关功能
1859 字
9 分钟
用户相关功能
【二】 登陆功能
【1】需求分析
【2】视图函数
from django.shortcuts import render, HttpResponsefrom django.urls import reversefrom utils.verify_code import create_verify_codefrom user.forms import RegisterFormfrom lib.CommonResponse import CommonResponsefrom user.models import UserInfofrom django.contrib import auth
def login(request): # 【1】判断当前请求方式为 POST 请求 并且当前请求是Ajax请求 if request.method == "POST" and request.is_ajax(): # 【2】从POST请求中获取得到 所有 POST 请求携带的数据 data = request.POST username = data.get("username") password = data.get("password") confirm_password = data.get("confirm_password") verify_code = data.get("verify_code") if not all([username, password, confirm_password, verify_code]): return CommonResponse(code=201, errors="请输入完整的信息!") # 【3】从request的session中获取得到验证码 true_code = request.session.get("verify_code") # 【4】校验当前输入的验证码和session中的验证码是否一致 if true_code.upper() != verify_code or not verify_code.upper(): return CommonResponse(code=201, errors="验证码错误!") # 【5】校验用户名是否存在 if not UserInfo.objects.filter(username=username).exists() or not username: return CommonResponse(code=202, errors="用户不存在!") # 【6】校验两次密码是否一致 if password != confirm_password or not password or not confirm_password: return CommonResponse(cpde=203, errors="两次密码不一致!") # 【7】通过 auth 模块校验用户名和密码是否正确 user_obj = auth.authenticate(username=username, password=confirm_password) if not user_obj: return CommonResponse(code=204, errors="用户名或密码错误!") # 【8】密码正确保存用户登录状态 auth.login(request, user_obj) # 【9】返回响应数据 return CommonResponse(code=200, message=f"当前用户 {user_obj.username} 登录成功!", next_url=reverse("home")) return render(request, "login.html", locals())
# 动态制作验证码图片def get_verify_img(request): # 调用工具类,获取验证码和验证码图片 code, img_data = create_verify_code() # 将验证码添加到 request 中 request.session["verify_code"] = code
# 将图片二进制数据返回 return HttpResponse(img_data)【3】前端页面
{% load static %}<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> {# <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>#} {# <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>#} <script src="{% static 'js/jquery.min.js' %}"></script> <script src="{% static 'plugins/bootstrap/js/bootstrap.min.js' %}"></script> <link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}"> <script src="{% static 'js/sweetalert.min.js' %}"></script> <script src="{% static 'plugins/layui/layui/layui.js' %}"></script> <link rel="stylesheet" href="{% static 'plugins/layui/layui/css/layui.css' %}"></head><body><div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">登陆界面</h1> {# 登陆采用 form 表单提交用户输入的数据,没什么特别的意思,就是想多换几种方式而已 #} {# <form action="" method="post"> #} {# 也可以采用 注册遍历form对象的方式 #} <form id="form_login"> {% csrf_token %} {# 用户名输入框 #} <div class="form-group"> <p> <label for="inputUsername"></label> 用户名 : <input type="text" class="form-control" id="inputUsername" name="username" placeholder="username"> </p> </div> {# 密码输入框 #} <div class="form-group"> <p> <label for="inputPassword"></label> 密码 : <input type="text" class="form-control" id="inputPassword" name="password" placeholder="password"> </p> </div> {# 确认密码输入框 #} <div class="form-group"> <p> <label for="inputConfirmPassword"></label> 确认密码 : <input type="text" class="form-control" id="inputConfirmPassword" name="confirm_password" placeholder="confirm_password"> </p> </div> {# 验证码输入框 #} <div class="form-group"> <p> 验证码 : <div class="row"> {# 验证码输入框 #} <div class="col-md-6"> <input type="text" class="form-control" name="verify_code"> </div> {# 渲染图片验证码 #} <div class="col-md-6"> {# 前端的 img 标签不只是能存放静态的图片文件路径,还能存动态的url链接 #} {# <img src="{% static 'avatar/default.png' %}" alt="图片走丢了 ~ ~ ~ " style="width: 360px;height: 36px;"> #} {# 后端返回的图片二进制数据可以正常渲染 #} {# <img src="{% url 'verify_img' %}" alt="图片走丢了 ~ ~ ~ " style="width: 360px;height: 36px;"> #} {# 动态渲染验证码图片 #} <img src="{% url 'verify_img' %}" alt="图片走丢了 ~ ~ ~ " style="width: 360px;height: 36px;" id="verify_code_img"> </div> </div> </p> </div> {# 用户提交数据按钮 #} {# <input type="submit" class="btn btn-block btn-info"> #} {# Ajax发送数据时点击的普通按钮,不触发 form 表单的自动刷新 #} <input type="button" class="btn btn-block btn-info" id="btn_login" value="提交"> </form> </div> </div></div>
<script> $(document).ready( // 给验证码图片绑定点击事件,点击验证码图片时,自动触发刷新,返回新的验证码 // ajax 绑定点击事件方式之一:委托事件 $("#verify_code_img").on("click", function () { // 【1】获取到当前 img 标签的 原来的 src 属性 let oldSrc = $(this).attr("src"); // 添加一个时间戳参数来确保 URL 不同 let timestamp = new Date().getTime(); // 【2】给当前旧src属性重新赋值 , 只要 src 的值和旧值不一致就会触发刷新 // 此方法 会不断的在路由后面拼接参数,导致路由太长 // $(this).attr("src", oldSrc + "?"); // 动态绑定当前时间戳作为参数 if (oldSrc.indexOf("?") > -1) { // 删除 旧src属性中 原有的时间戳参数 let newSrc = oldSrc.replace(/\?.*/, ''); $(this).attr("src", `${newSrc}?t=${timestamp}`); } else { // 如果是第一次则新增一个时间戳 $(this).attr("src", `${$(this).attr("src")}?t=${timestamp}`); } }),
// 发送请求方式二:Ajax遍历取值 $("#btn_login").on("click", function () { let data = {} $.each($("#form_login").serializeArray(), function (index, dataDict) { data[dataDict.name] = dataDict.value });
// 将 csrf token 放入数据中传给后端做校验 data["csrfmiddlewaretoken"] = "{{ csrf_token }}"; $.ajax({ url: "", type: "post", data: data, success: (response) => { // 回调函数处理逻辑 if (response.code === 200) { swal({ title: response.message, icon: "success", button: true, }).then(() => { window.location.href = response.next_url; }); } else { swal({ title: response.errors, icon: "error", button: true, }).then(() => { window.location.reload() }); } } }) }) );</script></body></html>【4】路由映射
from django.urls import pathfrom user.views import register, login, get_verify_img
urlpatterns = [ # 注册路由 path("register/", register, name="register"), # 登陆路由 path("login/", login, name="login"),
# 获取验证码图片 path("verify_img/", get_verify_img, name="verify_img"),]【三】修改密码
【1】需求分析
【2】视图函数
# 全局配置登陆跳转路由LOGIN_URL = reversed("login")# 修改密码接口@login_requireddef reset_password(request): # 【1】确认当前请求为 POST 请求并且是 Ajax 请求 if request.method == "POST" and request.is_ajax(): # 【2】获取前端传递的参数 username = request.user.username old_password = request.POST.get("old_password") new_password = request.POST.get("new_password") confirm_password = request.POST.get("confirm_password") # 【3】确保前端传入的参数有值 if not all([old_password, new_password, confirm_password]): return CommonResponse(code=201, errors="请补齐参数!") # 【4】确保两次密码存在并且一致 if new_password != confirm_password or not new_password or not confirm_password: return CommonResponse(code=202, errors="两次输入的密码不一致!") # 【5】通过 auth 模块校验原密码是否一致 old_password_is_right = auth.authenticate(username=username, password=old_password) if not old_password_is_right: return CommonResponse(code=203, errors="原密码输入错误!") # 【6】参数都正确,原密码正确,修改密码 request.user.set_password(confirm_password) # 不要忘了 save 保存,否则不生效 request.user.save() # 【7】退出当前登录用户,清除已经登录用户的数据 auth.logout(request) # 【8】返回前端信息 return CommonResponse(code=200, message=f"用户 {username} 密码修改成功!", next_url=reverse("login"))【3】前端页面
(1)触发按钮
{# 根据下面模态框中的属性弹出指定的模态框 #}<li><a href="" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>(2)模态框
{# 修改密码模态框开始 #}<div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> {# 右上角关闭模态框的 x #} <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> {# 大标题 : 修改密码页面 #} <h4 class="modal-title text-center" id="myLargeModalLabel">修改密码</h4> </div> <div class="modal-body"> <div class="row"> <div class="col-md-6 col-md-offset-3"> {# 定义form表单,但是仍然不走 form 表单提交数据,而是使用ajax #} <form id="reset_password_form"> <div class="form-group"> <label for="inputUsername">用户名 : </label> <input type="text" class="form-control" name="username" id="inputUsername" value="{{ request.user.username }}" disabled> </div> <div class="form-group"> <label for="inputOldPassword">旧密码 : </label> <input type="text" class="form-control" name="old_password" id="inputOldPassword" placeholder="old_password"> </div> <div class="form-group"> <label for="inputNewPassword">新密码 : </label> <input type="text" class="form-control" name="new_password" id="inputNewPassword" placeholder="new_password"> </div> <div class="form-group"> <label for="inputConfirmPassword">确认密码 : </label> <input type="text" class="form-control" name="confirm_password" id="inputConfirmPassword" placeholder="confirm_password"> </div> {# 定义点击修改按钮 #} <div class="form-group"> <input type="button" class="btn btn-warning btn-block" value="确认修改" id="btn_reset_password"> </div> </form> </div> </div> </div> </div> </div></div>{# 修改密码模态框结束 #}(3)Ajax请求
// 修改密码按钮点击事件$("#btn_reset_password").on("click", function () { // 使用 sweetalert 的弹框确认事件 swal({ title: "修改密码操作不可逆!", text: "一旦密码被修改,无法找回原密码,确认修改吗?", icon: "warning", buttons: true, dangerMode: true, }).then((willReset) => { // 判断用户是否点击了确认按钮 if (willReset) { let data = {} $.each($("#reset_password_form").serializeArray(), function (index, dataDict) { data[dataDict.name] = dataDict.value }) data["csrfmiddlewaretoken"] = "{{ csrf_token }}" $.ajax({ url: "{% url 'reset_password' %}", type: "post", data: data, success: (response) => { if (response.code === 200) { swal({ title: response.message, icon: "success", button: true, }).then(() => { window.location.href = response.next_url; }); } else { swal({ title: response.errors, icon: "error", button: true, }).then(() => { window.location.reload() }); } } }) } else { swal("好好想一想哦 ~ ~ ~ "); } });})【4】路由映射
【四】注销登录
【1】需求分析
【2】视图函数
@login_requireddef logout(request): auth.logout(request) return redirect("login")【3】前端页面
- 无前端页面
<li><a href="{% url 'logout' %}">注销登陆</a></li>【4】路由映射
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
C 语言发展史
编程语言了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。
2
C 语言开发环境的安装与配置
编程语言在 Windows、Linux 与 macOS 上安装 C 工具链,配置编辑器,并编译运行第一个 C 程序。
3
C 语言初识:程序运行机制与基本结构
编程语言认识 C 程序从源代码到运行的完整流程,以及基础语法和程序的基本结构。
4
C 语言基础:注释、关键字、变量与数据类型
编程语言学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。
5
C 语言数据类型
编程语言理解 C 语言的数据类型体系,包括基本类型、整数类型、浮点类型和逻辑类型。
随机文章随机推荐














