十日Python项目——第三日(用户中心——邮箱验证、修改密码)

#前言:

在最近十天我会用Python做一个购物类项目,会用到Django+Mysql+Redis+Vue等。

今天是第三天,主要负责撰写用户中心部分,以及优化登录部分。若是有不懂大家可以先阅读我的前两篇博客以能够顺承。博客:十日Python项目——第二天(用户登录)-CSDN博客

十日Python项目——第一天(用户注册)-CSDN博客

若是大家基础有不懂的,小编前面已经关于Django博客都更新完了,大家可以自行查看。若是有需要更改的地方欢迎大家指正,同时也欢迎大家关注点赞收藏等待后续,小编会尽力更新优质博客。

在此我会直接继承上一篇博客继续往下写。

九、用户中心:

首先用户中心我们要干什么:

这是我关于用户中心的一个简单设计,所以如图所示,我们需要做到能将用户的数据响应到页面,以及添加验证邮箱,修改密码等操作,今天博客我会讲解关于邮箱和修改密码操作。

1、响应用户中心:

注意:包括响应前端页面以及分发路由。

# 用户中心
path('info/' , views.UserInfoView.as_view() , name='info'),class UserInfoView(View):'''用户中心'''def get(self , request):return render(request , 'user_center_info.html')

2、判断登录状态:

因为我们要在用户中心进行各种操作首先我们得处于已经登录的状态。

实现 Django 用户认证提供 :LoginRequiredMixin 进行用户登录判断,实现这个功能直接继承该类即可。

from django.contrib.auth.mixins import LoginRequiredMixin #判断登陆状态要继承的类
class UserInfoView(LoginRequiredMixin,View):#先判断的登录再实现视图你,所以View继承在后面'''用户中心'''def get(self,request):return render(request,'user_center_info.html',context=context)#context=context就是把它也要响应到前端页面

注意也就是类继承认证模块。

在配置文件中重新定义认证登录重定向 url:

# 配置项目认证登录的重定向
LOGIN_URL = '/login/'

3、修改登录视图:

这里就是若是我们一开始没有登录,那么我们访问需要登录状态才能访问的页面才能访问的页面我们会重定向到登录页面,当我们登录后会继续重定向到刚刚我们要访问的页面。

在登录的post请求中添加:

next = request.GET.get('next')if next:# next 有值 , 重定向到指定的 urlresponse = redirect(next)else:# 响应首页中response = redirect('index')

上面代码的意思就是先获取登录的状态若是没登录返回首页,登录则返回要访问的页面。

所以此时的完整登录代码:

class LoginView(View):'''用户登录'''def get(self,request):return render(request,'login.html')def post(self,request):login_form=LoginForm(request.POST)if login_form.is_valid():username=login_form.cleaned_data.get('username')password=login_form.cleaned_data.get('password')remembered=login_form.cleaned_data.get('remembered')if not all([username,password]):#验证数据完整性return HttpResponse('缺少必要的数据')#通过认证模块,不要到数据库直接校验,因为数据是加密的。user=authenticate(username=username,password=password)#判断是否在数据库中获取到用户数据if user is None:return render(request,'login.html',{'account_errmsg':'用户名或者密码错误'})#状态保持login(request,user)#判断用户是否选择记住登录状态:if remembered:request.session.set_expiry(None)#默认记住14天else:request.session.set_expiry(0)#不记住登录状态,登录销毁next = request.GET.get('next')if next:# next 有值 , 重定向到指定的 urlresponse = redirect(next)else:# 响应首页中response = redirect('index')# 将用户名写入到 Cookie 中response.set_cookie('username', user.username, 3600)return responseelse:context={'forms_errmsg':login_form.errors}return render(request,'login.html',context=context)

4、获取用户数据:

获取用户数据也就是我们登陆后页面能显示出我们的用户名手机号等信息。

不是新创建的视图,而是原先视图,加上了获取信息,返回值里面context别忘

class UserInfoView(LoginRequiredMixin , View):'''用户中心'''def get(self , request):# 从 request 中获取用户信息context = {"username" : request.user.username,"mobile" : request.user.mobile,"email" : request.user.email}return render(request , 'user_center_info.html' , context=context)

前端页面响应:

<li><span>用户名:</span>[[ username ]]</li>
<li><span>联系方式:</span>[[ mobile ]]</li>

此时email还是没有信息的,所以我们无法响应。

5、添加邮箱:

首先要在模型数据库里面加上邮箱,其次验证邮箱,最后将邮箱写入数据库。

5.1、模型类中添加邮箱:

也就是多加了个Email,但是要注意,它一定是可以为空的,不然在注册那块过不去,因为我们注册那点没有涉及邮箱。
 

from django.db import models
from django.contrib.auth.models import  AbstractUser
#注意先不迁移(因为要用到继承)
class User(AbstractUser):'''用户数据认证模型类'''mobile=models.CharField(max_length=11,unique=True)email = models.EmailField(blank=True, null=True)  # 允许为空class Meta:db_table='user'

5.2、重写类方法:

验证登录的: LoginRequiredMixin 要求的返回值是 HttpResponse 对象或者其子类对象 , 如果返回的是 json 类型必须重写类方法。

在项目全局的 utils 包中创建一个 view 模块。

from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from utils.response_code import RETCODEclass LoginRequiredJsonMixin(LoginRequiredMixin):def handle_no_permission(self):# 重写方法 , 重新定义这个方法的返回值修改为 json 类型return JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'})

5.3、添加邮箱:

注意此时提交邮箱的方法是put请求。

# 添加邮箱
path('email/' , views.EmailView.as_view()),class EmailView(LoginRequiredJsonMixin , View):'''用户添加邮箱'''def put(self , request):# put 请求的参数放在 request 的请求体中 body 中,是一个以字节的方式传输数据# b'{'email':'123@com'}' ==> '{'email':'123@com'}' ==> {'email':'123@com'}email_dict = json.loads(request.body.decode())email = email_dict.get('email')# 数据校验if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$' , email):return HttpResponseForbidden('邮箱格式不正确')# 保存到数据库中request.user.email = emailrequest.user.save()# 添加成功return JsonResponse({'code':RETCODE.OK , 'errmsg':"ok"})

6、邮箱验证:

这里我们以网易邮箱为例

让 Django 发送邮件 , 是无法直接发送,需要借助 SMTP 服务器进行中转需要在 Django 项目的配置文件中配置邮箱需要的信息。

6.1、配置邮箱:

配置邮箱是为了我们能够验证发送邮箱等功能。

在设置中打开 POP3/SMTP/IMAP:

开启 IMAP/SMTP 和 POP3/SMTP
获取授权码(代码中会用到)

在settings文件下配置信息:

EMAIL_HOST_PASSWORD也就是上面我们提及的授权码。

# 发送邮件的配置参数
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 	# 指定邮件后端
EMAIL_HOST = 'smtp.163.com'	 	# 发邮件主机(网易邮箱)
EMAIL_PORT = 25		# 发邮件的端口
EMAIL_HOST_USER = '15609448850@163.com'  # 授权邮箱
EMAIL_HOST_PASSWORD = ''		# 邮箱授权时获取的密码,非登录邮箱的密码
EMAIL_FROM = 'AC-<15609448850@163.com>'		# 发件人抬头# 设置邮箱的激活连接
EMAIL_VERIFY_URL = 'http://127.0.0.1:8000/verification/'#端口号修改了的话自己别忘记修改

6.2、测试发送邮箱:

此时在tests文件下:

直接运行tests.py文件就可以做测试文件来发送数据消息。

from django.test import TestCase# Create your tests here.
if __name__=='__main__':import osos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ShopSystem.settings')import djangodjango.setup()from django.core.mail import send_mail# 邮件标题subject = '发送邮件 test'# 邮件正文(普通的没有格式的文本文件,字符串)message = '发送测试邮件'# 邮件正文(文件可以带有渲染格式)html_message = '<h1>发送测试邮件</h1>'# 发件人抬头from_email = 'AC-<15609448850@163.com>'# 收件人邮箱(列表格式)recipient_list = ['15609448850@163.com', ]send_mail(subject, message, from_email, recipient_list, html_message=html_message)

6.3、制作邮箱激活链接:

因为发送邮箱我们要验证的话会有激活链接:

首先安装好模块,最好是我指定的这个版本。

pip install itsdangerous==1.1.0

制作邮箱的激活连接 , 在 users 应用下的 utils中操作:

导入加密模块:

from itsdangerous import TimedJSONWebSignatureSerializer as TJWSS
def generate_verify_email_url(user):'''生成邮箱激活连接:param user: 用户数据:return: 返回加密的连接'''# 调用加密的方法s = TJWSS(SECRET_KEY , 600)# 获取用户的基本数据data = {'user_id':user.id , 'email':user.email}token = s.dumps(data)# http://127.0.0.1:8001/verification/?return EMAIL_VERIFY_URL+'?token='+ token.decode()

6.4、发送邮箱激活验证连接:

在用户保存邮箱之后,就发送邮箱激活验证连接。

class EmailView(View):'''用户添加邮箱'''def put(self , request):# put 请求的参数放在 request 的请求体中 body 中,是一个以字节的方式传输数据# b'{'email':'123@com'}' ==> '{'email':'123@com'}' ==> {'email':'123@com'}email_dict = json.loads(request.body.decode())email = email_dict.get('email')# 数据校验if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$' , email):return HttpResponseForbidden('邮箱格式不正确')# 保存到数据库中request.user.email = emailrequest.user.save()#调用生成邮箱的加密验证链接的方法verify_url=generate_verify_email_url(request.user)#发送验证邮箱# 邮件标题subject = '龙哥发的邮箱验证'# 邮件正文(文件可以带有渲染格式)html_message = f'<p>您的邮箱{email},点击链接进行验证激活邮箱</p>'\f'<p><a href="{verify_url}">{verify_url}</p>'# 收件人邮箱(列表格式)recipient_list = [email, ]send_mail(subject,'' ,from_email=settings.EMAIL_FROM,recipient_list=recipient_list, html_message=html_message)# 添加成功return JsonResponse({'code':RETCODE.OK , 'errmsg':"ok"})

6.5、邮箱验证:

验证要验证两个点:

1、数据库中是否已经存在该邮箱。

2、发送的邮箱链接是否和我们填写的验证上。

6.5.1、验证是否已经存在:

在 Django 中实现邮箱的数据验证 , 需要接收用书邮箱链接发送过来的参数

进行对参数解码 、校验。

同样是在utils文件:

def check_verify_email_token(token):'''校验邮箱链接中的参数:param token: 用户的加密邮箱链接:return: 用户数据 ; 数据不对返回 None'''s = TJWSS(SECRET_KEY, 600)data = s.loads(token)user_id = data.get('user_id')email = data.get('email')# 从数据库中查询是否有该用户try:user = User.objects.get(id=user_id , email=email)except Exception:return Noneelse:return user
6.5.1、链接验证:

实现验证邮箱视图

关于token都是与Ajax的参数对应的。

# 验证邮箱
path('verification/' , views.VerifyEmailView.as_view()),class VerifyEmailView(View):'''邮箱验证'''def get(self , request):token = request.GET.get('token')if not token:return HttpResponseForbidden('缺少必要的数据')# 调用解码验证方法user = check_verify_email_token(token)if not user:return HttpResponseForbidden('邮箱验证码失败')# 判断用户是否以验证邮箱if user.is_active == 0:# 用户没有验证邮箱user.is_active = 1user.save()else:return HttpResponseForbidden('用户以验证邮箱')# 验证成功 , 重定向到用户中心return redirect('/info/')

注意:判断user.is_active是0/1,这是在数据库中自动生成的字段,具体叫什么可以自行上数据库查看,但是参数的判别不会有错。

7、修改密码:

修改密码主要涉及的操作就是:

1、验证旧密码是否正确

2、判断新密码是否合法且一致

3、修改好后要清楚用户的登录状态(也就是前面提到的退出登录),再重定向到登录页面重新登录。

注意:因为他也是验证我们自己提交的数据所以参数名和我们的Ajax名一致。

# 修改密码
path('changepwd/' , views.ChangePasswordView.as_view() , name='changepwd'),class ChangePasswordView(View):'''修改密码'''def get(self , request):return render(request , 'user_center_pass.html')def post(self , request):# 接收用户输入的密码数据old_password = request.POST.get('old_password')new_password = request.POST.get('new_password')new_password2 = request.POST.get('new_password2')# 校验数据 , 数据是否完整if not all([old_password , new_password , new_password2]):return HttpResponseForbidden('缺少必要的数据')# 校验旧密码是否正确if not request.user.check_password(old_password):return render(request , 'user_center_pass.html' , {'origin_password_errmsg':'当前密码不正确'})# 校验新密码中的数据是否合法if not re.match(r'^[0-9a-zA-Z]{6,20}$' , new_password):return render(request , 'user_center_pass.html' , {'change_password_errmsg':'密码格式不正确'})# 校验两次密码是否一致if new_password != new_password2:return render(request, 'user_center_pass.html', {'change_password_errmsg': '两次密码不一致'})# 密码合法 , 将新的密码重新保存request.user.set_password(new_password)request.user.save()# 更新用户的状态保持 , 清理原有的密码数据logout(request)response = redirect('login')response.delete_cookie('username')return response

#总结:
今天的用户中心我们最难点就是邮箱的添加验证同样用到很多方法串联。全局许多东西都是需要前后端对应,尤其与Ajax要对应。后续小编会更新项目其它内容,欢迎大家关注,同时也欢迎大家评论指正。

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

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

相关文章

C++——验证二叉搜索树leetcode98

C——验证二叉搜索树leetcode98 题目描述思路代码 题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树…

前端江湖:从菜鸟到大侠的修炼手册

在这个数字编织的梦幻世界里&#xff0c;前端&#xff0c;这个听起来就带着几分仙气与神秘感的词汇&#xff0c;实则是每一位互联网探险家手中的魔法杖。它不仅连接着代码的冰冷逻辑与用户的炽热情感&#xff0c;更在无数次的点击与滑动间&#xff0c;绘制出一幅幅绚丽多彩的交…

yolov8.1超简单环境搭建、标注、训练、转onnx、转输出维度

1.显卡驱动查看 nvidia-smi 2.yolo源码与模型 https://hub.nuaa.cf/ultralytics/ultralytics https://github.com/ultralytics/ultralytics 3.anaconda https://www.anaconda.com/download或 https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe …

Godot入门 05收集物品

创建新场景&#xff0c;添加Area2D节点&#xff0c;AnimatedSprite2D节点 &#xff0c;CollisionShape2D节点 添加硬币 按F键居中&#xff0c;放大视图。设置动画速度设为10FPS&#xff0c;加载后自动播放&#xff0c;动画循环 碰撞形状设为圆形&#xff0c;修改Area2D节点为Co…

[K8S] K8S资源控制器Controller Manager(4)

文章目录 1. 常见的Pod控制器及含义2. Replication Controller控制器2.1 部署ReplicaSet 3. Deployment3.1部署Deployment3.2 运行Deployment3.3 镜像更新方式3.4 Deployment扩容3.5 滚动更新3.6 金丝雀发布(灰度发布)3.7 Deployment版本回退3.8 Deployment 更新策略 4. Daemon…

Go语言常见序列化协议全面对比

先说结论 从易用性、性能、内存占用、编码后大小等几个方面综合考虑 ProtoBuf 胜出。 Gob 从性能和 I/O 带宽占用上都和 ProtoBuf 差不多&#xff0c;唯一劣势是编解码时内存占用较多。考虑到不用再写 IDL 带来的易用性&#xff0c;如果整个系统内不存在使用除 Go 以外其他语言…

高可用高并发常见问题以及答案

什么是高可用系统?如何评估系统的可用性? 高可用系统是指系统能够以高度的稳定性和可靠性运行,即使在面对硬件或软件故障时也能保持正常运行。可用性通常通过系统的 downtime(不可用时间)来评估,例如通过 SLA(Service Level Agreement)来定义系统在特定时间段内可用的…

人工智能与机器学习原理精解【7】

文章目录 凸优化基础理论加权正规方程线性回归模型加权最小二乘法加权正规方程注意使用Diagonal函数使用diagm函数总结 加权最小二乘法加权最小二乘法的定义加权最小二乘法的算法加权最小二乘法的计算加权最小二乘法的原理一、基本思想二、原理详解三、总结 加权最小二乘法的例…

贸易壁垒的作用及影响

目录 什么是贸易壁垒 关税壁垒和非关税壁垒 贸易壁垒的好处 贸易壁垒的负面影响 什么是贸易壁垒 贸易壁垒又称贸易障碍&#xff0c;一般分关税壁垒和非关税壁垒两类。 所谓关税壁垒&#xff0c;是指进出口商品经过一国关境时&#xff0c;由政府所设置的海关向进出口商征收…

外卖霸王餐系统推荐,哪家的系统比较稳定呢?

以下是一些较为稳定且有一定用户基础的外卖霸王餐系统&#xff0c;你可以根据自身需求进一步考察和选择&#xff1a; - **饭否霸王餐**&#xff1a;有专门的APP&#xff0c;如在应用宝上其开发商为南京有惠鲸选电子商务有限公司。它覆盖了多个城市&#xff0c;提供美团、饿了么…

巴黎奥运启幕 PLM系统助力中国制造闪耀全球

2024巴黎奥运会将于法国当地时间7月26日在塞纳河畔正式开幕。即将亮相巴黎奥运会赛场的除了中国运动员之外&#xff0c;还有一批批中国制造企业为奥运会设计并制造的体育设备也将惊艳亮相&#xff0c;成为赛场上另一道亮丽的风景线。 在新时代的浪潮中&#xff0c;中国制造业坚…

Centos7安装Windows系统默认字体

Centos7安装Windows系统默认字体 拷贝windows系统默认字体&#xff08;建议拷贝所有&#xff09;c:\windows\fonts 查看系统默认字体&#xff1a;fc-list 查看系统安装的中文字体&#xff1a;fc-list :langzh 执行&#xff1a; a) sudo yum install -y fontconfig mkfontsca…

AlibabaCloudAI

快速体验 Spring Cloud Alibaba AI JDK要求最低17 1.SpringAI Spring AI 旨在简化包含人工智能相关功能的应用程序的开发&#xff0c;避免不必要的复杂性。 Spring AI 的核心是提供抽象&#xff0c;作为开发 AI 应用程序的基础。这些抽象有多种实现方式&#xff0c;只需极少…

【进阶】Python使用selenium 访问网页完成登录操作页面异常时——最全重试机制汇总

文章目录 思路一:使用添加异常重试机制 [常用]思路二:使用装饰器实现重试机制 [常用]思路三:使用更复杂的异常处理和恢复机制思路四:结合日志记录与重试思路五:使用递归实现重试机制思路六:结合外部配置文件管理重试参数思路七:使用自定义异常类来处理特定错误思路八:使…

Java小白入门到实战应用教程-运算符详解

Java小白入门到实战应用教程-运算符 上节回顾 在上节的内容中我们了解了变量和基本数据类型的内容&#xff0c;现在回顾一下上节课的内容。 声明变量的语法为&#xff1a; 数据类型 变量名&#xff1b; 其中在java中一共有8中基本数据类型&#xff0c;分别是&#xff1a;b…

三维影像系统PACS源码,图像存储与传输系统,应用于医院中管理医疗设备如CT,MR等产生的医学图像的信息系统

PACS&#xff0c;即图像存储与传输系统&#xff0c;是应用于医院中管理医疗设备如CT&#xff0c;MR等产生的医学图像的信息系统。目标是支持在医院内部所有关于图像的活动&#xff0c;集成了医疗设备&#xff0c;图像存储和分发&#xff0c;数字图像在重要诊断和会诊时的显示&a…

【linux】【设备树】具有 GPIO 控制器和连接器的硬件配置的备树(Device Tree)代码讲解

具有 GPIO 控制器和连接器的硬件配置的备树&#xff08;Device Tree&#xff09;代码讲解 背景 -学习Linux设备树 代码 soc {soc_gpio1: gpio-controller1 {#gpio-cells <2>;};soc_gpio2: gpio-controller2 {#gpio-cells <2>;}; };connector: connector {#gpi…

零侵入零代码零配置全自动接口文档生成可在线调试框架doc-apis它来了!

近期开源了一款全自动零侵入零代码零配置接口文档生成框架doc-apis,实测只要代码符合规范,即可生成多端多语种多格式的接口文档,适合敏捷开发,欢迎大家试用,另外也恳请大家帮忙点一下star,帮助开源项目走得更远,让更多人知道,非常感谢! # 官方地址 | Official website --- **…

OD C卷 - 宽度最小的子矩阵

宽度最小的子矩阵 &#xff08;100&#xff09; 给定一个n行 * m列的矩阵&#xff1b;给定一个k个整数的数组k_list&#xff1b;在n*m的矩阵中找一个宽度最小的子矩阵&#xff0c;该子矩阵包含k_list中所有的整数&#xff1b; 输入描述&#xff1a; 第一行输入n,m 两个整数&am…

Redis的五种数据类型与命令

目录 引言 一 Redis的特性 二 Redis的安装 三 Redis的优点 四 Redis的五种数据类型与命令 五 Redis的配置文件 引言 Redis是什么&#xff1f; Remote Dictionary Service(远程字典服务器) Redis 是一个开源的(BSD许可)的&#xff0c;C语言编写的&#xff0c;高性能的数…