前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >零基础使用Django2.0.1打造在线教育网站(十四):用户密码找回

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

原创
作者头像
啃饼思录
修改2018-09-10 21:34:08
9440
修改2018-09-10 21:34:08
举报

关于博主

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

代码语言:txt
复制
                 微信公众号:  啃饼思录
代码语言:txt
复制
                 QQ: 2810706745(啃饼小白)

写在前面

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

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

用户激活的操作

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

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

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

代码语言:txt
复制
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文件,我们设置默认未激活:

代码语言:txt
复制
# 默认激活状态为False,也就是未激活
user_profile.is_active = False

并且在下面新增代码:

代码语言:txt
复制
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函数,我们当时没有判断用户是否激活,现在需要判断,修改代码如下:

代码语言:txt
复制
 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,我们来测试一下,在图中所示位置打上断点,开始调试:

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

代码语言:txt
复制
请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/HekaM6EfZfeKy1Zc

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

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

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

代码语言:txt
复制
    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文件,里面就几行代码:

代码语言:txt
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>链接失效</title>
</head>
<body>
<p>对不起,链接失效了</p>
</body>
</html>

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

代码语言:txt
复制
# 用于实现用户激活操作的函数
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文件,在里面添加如下代码:

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

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

代码语言:txt
复制
from users.views import  ForgetPwdView

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

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

代码语言:txt
复制
<a class="fr" href="forgetpwd.html">忘记密码?</a>

修改为:

代码语言:txt
复制
 <a class="fr" href="{% url 'forget_pwd' %}">忘记密码?</a>

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

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

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

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

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

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

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

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

代码语言:txt
复制
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那一行,并修改为:

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

页面正常显示了!

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

里面添加如下代码:

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

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

代码语言:txt
复制
# 用于实现用户忘记码(找回密码)的函数
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文件,在里面添加如下代码:

代码语言:txt
复制
# 用于实现用户重置密码的函数
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信息:

代码语言:txt
复制
from users.views import  ResetView

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

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

代码语言:txt
复制
 <input type="hidden" name="email" value="{{ email }}">
就是这个样子:

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

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

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

然后step out结束:

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

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

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

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

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

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

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

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

代码语言:txt
复制
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中的配置是这样的:

代码语言:txt
复制
re_path('reset/(?P<active_code>.*)/', ResetView.as_view(), name="reset_pwd"),

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

代码语言:txt
复制
 action="{% url 'reset_pwd' %}"

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

代码语言:txt
复制
from users.views import  ModifyPwdView

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

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

代码语言:txt
复制
# 用于实现用户修改密码的函数
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})
也就是这个样子:

然后修改前端页面:

代码语言:txt
复制
<form id="reset_password_form" action="{% url 'modify_pwd' %}" method="post">
也就是这个样子:

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

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

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

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

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

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

Pycharm中的调试

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

代码语言:txt
复制
F5:跳入方法
F6:向下逐行调试
F7:跳出方法
F8:直接跳转到下一个断点

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

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

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

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

****

  • 1、step over(F8)作用是在同一个调用栈层中移动到下一个可执行的代码行。如果当前行是一个函数调用,则调试器将在函数调用之后的下一条语句停止。调试器不会进入函数体。如果当前行是函数的最后一行,则step-over将进入下一个栈层,并在调用函数的下一行停止。?developer/article/1331062/undefined?developer/article/1331062/undefined?developer/article/1331062/undefined?developer/article/1331062/undefined?developer/article/1331062/undefined?developer/article/1331062/undefined?developer/article/1331062/undefined
  • 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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于博主
  • 写在前面
  • 用户激活的操作
  • 忘记密码的操作
    • 拷贝forgetpwd页面
      • 定义(忘记)找回密码的视图
      • 重置密码的操作
        • 拷贝password_reset.html页面
          • 定义重置密码的视图
          • Pycharm中的调试
          相关产品与服务
          验证码
          腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
          http://www.vxiaotou.com