零基础使用Django2.0.1打造在线教育网站(十四):用户密码找回

关于博主

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

                 微信公众号:  啃饼思录
                 QQ: 2810706745(啃饼小白)

写在前面

本篇笔记我们将实现用户的激活,用户密码找回,重置密码,修改密码等功能,前面所介绍的知识大家没事可以复习一下,加深对知识的理解和应用,后面很多东西就是前面讲过的知识的应用。

本篇笔记对应于第十四篇代码,对应于github的位置是https://github.com/licheetools/eduline

用户激活的操作

打开我们的Navicat,去数据库中找到我们的用户信息表:

这里面有个字段is_active,它是用来判别用户是否激活的,默认是未激活也就是0,这里都是1肯定是不行的,所以我们需要定义激活用户的函数,来完成用户的激活操作。

先配置一下路径path,打开eduline/urls.py文件,在里面添加一行代码:

from django.urls import  re_path
from users.views import ActiveUserView  #ActiveUserView目前未定义,后面马上定义


# 激活用户url
re_path('active/(?P<active_code>.*)/', ActiveUserView.as_view(), name="user_active")

'active/(?P<active_code>.*)/'是正则表达式模式,用于匹配验证码!

打开users/views.py文件,我们设置默认未激活:

# 默认激活状态为False,也就是未激活
user_profile.is_active = False

并且在下面新增代码:

from .models import EmailVerifyRecord

# 用于实现用户激活操作的函数
class ActiveUserView(View):
    def get(self, request, active_code):
        # 用于查询邮箱验证码是否存在
        all_record = EmailVerifyRecord.objects.filter(code=active_code)
 
        if all_record:
            for record in all_record:
                # 获取到对应的邮箱
                email = record.email
                # 查找到邮箱对应的用户
                user = UserProfile.objects.filter(email=email)
                user.is_active = True #激活用户
                user.save()
                # 激活成功跳转到登录页面
            return render(request, "login.html")

现在回到我们的LoginView函数,我们当时没有判断用户是否激活,现在需要判断,修改代码如下:

 if user is not None:
                if user.is_active:
                    # login 有两个参数:request和user。我们在请求的时候,request实际上是写进了一部分信息,然后在render的时候,这些信息也被返回前端页面从而完成用户登录
                    login(request, user)
                    # 页面跳转至网站首页 user request也会被带回到首页,显示登录状态
                    return render(request, "index.html")
                else:
                    return render(request, "login.html", {'msg': '用户未激活!'})
            else:
                # 说明里面的值是None,再次跳转回主页面并报错,这里仅当用户密码出错时才返回
                return render(request, "login.html", {'msg': '用户名或者密码错误!'})
将数据表中的licheetools@sina.cn 用户的is_active修改为0,我们来测试一下,在图中所示位置打上断点,开始调试:

我们的用户测试激活调试没有问题,再来看一下验证码激活:我们去新浪邮箱,将获取到的链接访问一下:

请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/HekaM6EfZfeKy1Zc

按图示来测试一下,也没有问题!

至此,我们完成了邮箱验证码的激活以及用户的激活。

不过我们还有两个问题,一个就是前面没有判断邮箱是否已经存在,我们不能用旧的邮箱来注册,所以我们需要配置一下,打开users/views.py文件,修改代码如下:

    def post(self, request):
        # 类的实例化需要一个字典dict参数,而前面我们就知道request.POST是一个QueryDict,所以可以直接传入POST中的信息
        register_form = RegisterForm(request.POST)
        if register_form.is_valid():
            user_name = request.POST.get("email", "")
            if UserProfile.objects.filter(email=user_name):
                # register_form回填信息必须有,msg是信息提示
                return render(request, 'register.html', {'register_form': register_form}, {'msg': '该邮箱已被注册过了'})
            else:
                # password为前端页面name的返回值,取到用户名和密码我们就开始进行登录验证;取不到时为空。
                pass_word = request.POST.get("password", "")
                # 实例化一个user_profile对象,存入前端页面获取的值
                user_profile = UserProfile()
                user_profile.username = user_name
                user_profile.email = user_name

                # 默认激活状态为False,也就是未激活
                user_profile.is_active = False

                # 对password进行加密并保存
                user_profile.password = make_password(pass_word)
                user_profile.save()
                send_register_eamil(user_name, 'register')
                pass

另一个就是我们对于链接的处理不够完善,正如你所了解的那样,链接肯定有有效时间,在这个规定的时间内点击才有用,过了规定时间就没有用,所以我们需要新建一个链接超时的html文件:新建active_fail.html文件,里面就几行代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>链接失效</title>
</head>
<body>
<p>对不起,链接失效了</p>
</body>
</html>

然后我们来users/views.py文件,修改一下激活的代码:

# 用于实现用户激活操作的函数
class ActiveUserView(View):
    def get(self, request, active_code):
        # 用于查询邮箱验证码是否存在
        all_record = EmailVerifyRecord.objects.filter(code=active_code)
        if all_record:
            for record in all_record:
                # 获取到对应的邮箱
                email = record.email
                # 查找到邮箱对应的用户
                user = UserProfile.objects.filter(email=email)
                user.is_active = True
                user.save()
        else:
            return render(request, "active_fail.html")
        # 激活成功跳转到登录页面
        return render(request, "login.html")
按照图示打上断点并开始调试:

调试没有问题!

好,解决了上面两个问题之后,下面我们来进行忘记密码,找回密码的操作。

忘记密码的操作

拷贝forgetpwd页面

forgetpwd.html页面拷贝到我们的templates文件夹里面:

定义(忘记)找回密码的视图

打开users/views.py文件,在里面添加如下代码:

# 用于实现用户忘记码(找回密码)的函数
class ForgetPwdView(View):
    def get(self, request):
        return render(request, "forgetpwd.html", {})

然后在eduline/urls.py文件里面配置url信息:

from users.views import  ForgetPwdView

# 找回密码url,注意是普通的url
path("forget/", ForgetPwdView.as_view(), name="forget_pwd"),

接下来配置跳转路径,首先ctrl+F 搜索login.html,找到忘记密码,修改href属性:

<a class="fr" href="forgetpwd.html">忘记密码?</a>

修改为:

 <a class="fr" href="{% url 'forget_pwd' %}">忘记密码?</a>

注意外部有双引号,里面就只能使用单引号。

接着继续修改forgetpwd.html页面的跳转链接,一样的操作,这里就不演示了!

现在运行一下我们的项目,在浏览器地址栏中输入:http://127.0.0.1:8000/forget/,出现了:

样式没有加载出来,我们需要和前面的一样,加上静态相对路径,忘记的小伙伴可以查看第十一篇笔记:零基础使用Django2.0.1打造在线教育网站(十一):登录页面实现

1、页面第三行加上{% load staticfiles %}
2、修改全部类型文件的static相对路径
3、修改其中的url,配置跳转链接
配置完刷新一下页面:

这个页面其实也是一个表单,所以需要定义form表单,我们可以仿照注册的表单来书写,打开我们的users/forms.py文件,在里面添加一下代码:

# 用户找回密码时的表单,注意字段与前端页面保持一致
class ForgetForm(forms.Form):
    email = forms.CharField(required=True)  # 用户名不能为空
    captcha = CaptchaField(error_messages={"invalid": "验证码错误"})

接着回到我们的views.py文件,继续完善ForgetPwdView:

from users.forms import  ForgetForm

# 用于实现用户忘记码(找回密码)的函数
class ForgetPwdView(View):
    def get(self, request):
        forget_form = ForgetForm()
        return render(request, "forgetpwd.html", {'forget_form': forget_form})

然后回到我们的forgetpwd.html页面,我们删除captcha那一行,并修改为:

<div class="form-group captcha1 marb38">
                        <label>验&nbsp;证&nbsp;码</label>
                        {{ forget_form.captcha }}
 </div>
我们再来刷新一下我们的页面:

页面正常显示了!

既然我们是找回密码,那么我们肯定需要发送邮件,我们前面新建了发送失败的html页面,那我们肯定也需要新建一个发送成功的html页面吧,新建send_success.html文件:

里面添加如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>邮件发送成功</title>
</head>
<body>
<p>邮件已发送,请注意查收!</p>
</body>
</html>

还是回到我们的views.py文件,继续完善ForgetPwdView的post方法:

# 用于实现用户忘记码(找回密码)的函数
class ForgetPwdView(View):
    def get(self, request):
        forget_form = ForgetForm()
        return render(request, "forgetpwd.html", {'forget_form': forget_form})

    def post(self, request):
        forget_form = ForgetForm(request.POST)
        if forget_form.is_valid():
            email = request.POST.get('email', '')
            # 发送找回密码的邮件
            send_register_eamil(email, 'forget')
            return render(request, 'send_success.html')
        else:
            return render(request, "forgetpwd.html", {'forget_form': forget_form})

再回到前端页面,看看这些是不是都修改完了:

还有页面的提示信息也要修改(参考前面的介绍):

至此,我们密码找回就已经完成了,我们来测试一下:

测试成功了!

下面完成重置密码和修改密码的操作!

重置密码的操作

拷贝password_reset.html页面

password_reset.html页面拷贝到我们的templates文件夹里面:

定义重置密码的视图

打开users/views.py文件,在里面添加如下代码:

# 用于实现用户重置密码的函数
class ResetView(View):
    def get(self, request, active_code):
        # 用于查询邮箱验证码是否存在
        all_record = EmailVerifyRecord.objects.filter(code=active_code)
        if all_record:
            for record in all_record:
                # 获取到对应的邮箱
                email = record.email
                # 查找到邮箱对应的用户
                return render(request, "password_reset.html", {"email": email})   # 告诉页面是哪个用户在重置密码
        else:
            return render(request, "active_fail.html")
        # 激活成功跳转到登录页面
        return render(request, "login.html")

然后在eduline/urls.py文件里面配置url信息:

from users.views import  ResetView

 # 密码重置url
    re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name="reset_pwd"),

接下来我们在页面隐式回填刚才的email,在password_reset.html页面,添加下面一行代码:

 <input type="hidden" name="email" value="{{ email }}">
就是这个样子:

现在调试一下我们的项目,在图示位置打上断点:

接着我们登录新浪邮箱(前面是QQ邮箱就用QQ邮箱),查找我们的之前的重置密码邮件:

接着将重置密码链接复制到浏览器地址栏打开,页面进入到Pycharm出现了:

然后step out结束:

还记得我们刚才在里面加的那个input么,它的作用是告知页面哪个用户此时此刻正在重置密码,我们点击查看网页源代码,看是不是input起了作用:

看到没有,确实起了作用,不过我们除非查看了源码,否则是看不到的!

不过样式没有加载出来,我们需要和前面的一样,加上静态相对路径,忘记的小伙伴可以查看第十一篇笔记:零基础使用Django2.0.1打造在线教育网站(十一):登录页面实现

1、页面第三行加上{% load staticfiles %}
2、修改全部类型文件的static相对路径
3、修改其中的url,配置跳转链接

配置完以后我们刷新页面会出错,这是正常现象,因为我们在url跳转时缺少参数,这个先放在这里(如果你为了不影响心情,可以不刷新页面)!

刚才那个页面其实也是一个表单,所以需要定义form表单,我们可以仿照注册的表单来书写,打开我们的users/forms.py文件,在里面添加一下代码:

# 用户修改密码时的表单,注意字段与前端页面保持一致
class ModifyPwdForm(forms.Form):
    password1 = forms.CharField(required=True, min_length=5)  # 新密码不能为空
    password2 = forms.CharField(required=True, min_length=5)  # 确认密码不能为空
记得与前端页面字段一致:

接着回到我们的views.py文件,继续完善ResetView:

from users.forms import  ModifyPwdForm

    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1 = request.POST.get("password1", '')
            pwd2 = request.POST.get("password2", '')
            email = request.POST.get("email", '')
            # 如果前后两次密码不相等,那么回填信息并返回错误提示
            if pwd1 != pwd2:
                return render(request, "password_reset.html", {"email": email, "msg": "对不起,前后密码不一致"})
            # 如果前后两次密码相等,那么进入我们的密码修改保存
            # 取出用户信息
            user = UserProfile.objects.get(email=email)
            # 随意取出一个密码并将其进行加密
            user.password = make_password(pwd1)
            # 将更新后的用户信息保存到数据库里面
            user.save()
            # 密码重置成功以后,跳转到登录页面
            return render(request, "login.html", {"msg": "恭喜您,您的密码修改成功,请登录"})
        else:
            email = request.POST.get("email", '')
            return render(request, "password_reset.html", {"email": email, "modify_form": modify_form})

我们现在来解决刚才url出错的问题,我们在path中的配置是这样的:

re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name="reset_pwd"),

它和我们普通的path不一样,里面有一个匹配active_code的正则表达式,所以在前端页面不能和普通的url那样写:

 action="{% url 'reset_pwd' %}"

既然不能这样写,那我们可以用一个普通的path来定义它,作用是修改密码即可:

from users.views import  ModifyPwdView

# 修改密码url
path("modify/", ModifyPwdView.as_view(), name="modify_pwd"),

这里面的ModifyPwdView是我们新建的视图函数,可以将前面的ResetView中的post方法脱离出来,成为ModifyPwdView的一部分:

# 用于实现用户修改密码的函数
class ModifyPwdView(View):
    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1 = request.POST.get("password1", '')
            pwd2 = request.POST.get("password2", '')
            email = request.POST.get("email", '')
            # 如果前后两次密码不相等,那么回填信息并返回错误提示
            if pwd1 != pwd2:
                return render(request, "password_reset.html", {"email": email, "msg": "对不起,前后密码不一致"})
            # 如果前后两次密码相等,那么进入我们的密码修改保存
            # 取出用户信息
            user = UserProfile.objects.get(email=email)
            # 随意取出一个密码并将其进行加密
            user.password = make_password(pwd1)
            # 将更新后的用户信息保存到数据库里面
            user.save()
            # 密码重置成功以后,跳转到登录页面
            return render(request, "login.html", {"msg": "恭喜您,您的密码修改成功,请登录"})
        else:
            email = request.POST.get("email", '')
            return render(request, "password_reset.html", {"email": email, "modify_form": modify_form})
也就是这个样子:

然后修改前端页面:

<form id="reset_password_form" action="{% url 'modify_pwd' %}" method="post">
也就是这个样子:

在图示位置打上断点,开始调试我们的项目,具体操作和前面类似,这里就不介绍了。

复制密码重置链接去浏览器地址栏打开,输入新的密码:

然后点击提交按钮,就进入下面的Pycharm页面:

注意:如果点击提交按钮没有反应,页面没有进入view.py里面的方法,可能是按钮的类型错了,type="submit"而不是type="button",也就是这个样子:

最后,修改password_reset.html的错误信息的提示:

前面说了这么多调试命令,小伙伴们可能会不太明白其中的意思,下面我详细介绍一下Pycharm是如何调试代码的!

Pycharm中的调试

如果你熟悉Eclipse,那你肯定知道它的快捷键:

F5:跳入方法
F6:向下逐行调试
F7:跳出方法
F8:直接跳转到下一个断点

当然Pycharm也是可以采用Eclipse的快捷键来调试代码的,具体设置方法如下:

点击File--> Settings--> Apperance--> Keymap--> 右侧下拉选Eclipse--> Apply --> OK这几步就完成了,没看懂的可以看下面的图片(记得按照序号的顺序来操作哈)

当然如果你没用过Eclipse,也不想记那些快捷键,这也是可以的,那看下面的图片:

这个页面你总是经常看到吧,下面分别解释一下各个键的名称及功能作用(括号内是默认的快捷键,也就是Pycharm自己设定的):

****

  • 1、step over(F8)作用是在同一个调用栈层中移动到下一个可执行的代码行。如果当前行是一个函数调用,则调试器将在函数调用之后的下一条语句停止。调试器不会进入函数体。如果当前行是函数的最后一行,则step-over将进入下一个栈层,并在调用函数的下一行停止。undefinedundefinedundefinedundefinedundefinedundefinedundefined
  • 2、step into(F7)作用是移动到下一个可执行的代码行。如果当前行是一个函数调用,则调试器将进入函数,并停止在函数体的第一行。step-into可以帮助初步揭开代码位置的谜团。例如,函数调用和函数本身可能在不同的文件中是函数的最后一行,则step-over将进入下一个栈层,并在调用函数的下一行停止。
  • 3、Force step into(Ctrl+shift+F7)可以看做是step into的升级版本,可以越过代码,强力执行。
  • 4、step-out(shift+F8)作用是在栈中前进到下一层,并在调用函数的下一行停止。

还有,如果你有多个断点,如何在pycharm中从第一个断点跳转至第二个断点呢?

例如第一个断点在第一行,第二个断点在第五十行,那么开始debug后,你首先停在第一行,随后点击菜单栏的Run-> Resume Program即可跳转至第二个断点了,是不是很简单!

至此,关于用户的激活,用户密码找回,重置密码,修改密码,调试代码等功能的介绍就到此为止,感谢你的赏阅!

本篇笔记对应于第十四篇代码,对应于github的位置是https://github.com/licheetools/eduline

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏计算机编程

ionic4 -- angular 跳转页面

ionic4 与前辈们最大的不同就是通过angular引入了route,这样每次跳转的时候只需要直接跳转对应的路由地址就可以了,给了路由器上的解耦,也解决了原来...

1K2
来自专栏编程心路

SSH框架之旅-struts2(4)

AOP 是 Aspect Objected Prograing(面向切面编程)的缩写。struts2 中的拦截器就是这种编程策略的一种实现,AOP 思想是在基本...

1403
来自专栏王二麻子IT技术交流园地

二、VueJs 填坑日记之基础项目构建

在上一篇文章中,大致介绍了一下本系列博文以及学习vuejs我们需要了解的一些概念,希望大家认真阅读,所谓知己知彼,百战百胜,学习也一样,工欲善其事,必先利其器,...

2137
来自专栏游戏杂谈

Linux下使用rsync同步文件

遇到的问题是几台游戏服务器,有一台新的服务器之前已经copy(Linux的scp命令)过文件上去,但在测试的过程中发现还是图片无法正常不显示出来,然后用http...

3912
来自专栏码洞

RPC 服务器之【多进程描述符传递】高阶模型

今天老师要给大家介绍一个比较特别的 RPC 服务器模型,这个模型不同于 Nginx、不同于 Redis、不同于 Apache、不同于 Tornado、不同于 N...

1322
来自专栏玄魂工作室

Hacker基础之Linux篇:基础Linux命令五

1. vi vi命令是UNIX操作系统和类UNIX操作系统中最通用的全屏幕纯文本编辑器。 Linux中一般默认安装的的编辑器叫vi,而vim是vi的增强版(vi...

2816
来自专栏有趣的django

Django用户登录与注册系统

一、创建项目 1.1.创建项目和app django-admin startproject mysite_login python manage.py sta...

1.8K7
来自专栏Porschev[钟慰]的专栏

Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

前言   前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子   上传功能命名用formidabl...

2549
来自专栏蜉蝣禅修之道

openipmp安装

1983
来自专栏祥子的故事

python | os包常用命令介绍

3915

扫码关注云+社区

领取腾讯云代金券