写在前面
本篇笔记我们将实现用户的激活,用户密码找回,重置密码,修改密码等功能,前面所介绍的知识大家没事可以复习一下,加深对知识的理解和应用,后面很多东西就是前面讲过的知识的应用。
本篇笔记对应于第十四篇代码,对应于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>验 证 码</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将进入下一个栈层,并在调用函数的下一行停止。
- 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。
网友评论