10、Django实战第10天:找回密码
今天完成的功能是:用户忘记密码后,通过注册邮箱重置密码...
首先还是把前端页面准备好,把forgetpwd.html复制到templates目录下
编辑users.views.py,创建一个忘记密码的类
class ForgetPwdView(View): def get(self, request): return render(request, 'forgetpwd.html', {})
配置一条url
... from users.views import ForgetPwdView urlpatterns = [ ... url(r'^forget/$', ForgetPwdView.as_view(), name='forget_pwd'), ]
在login.html中,编辑"忘记密码"的url, 顺便把注册也改一下
把forgetpwd.html中的静态文件路径都改下(css/images/js)
然后我们访问这个页面如下:127.0.0.1:8000/forget/
忘记密码需要输入注册时的邮箱,还要填写验证码。因此我们也需要对这两个表单进行form验证,编辑users.forms.py
class ForgetForm(forms.Form): email = forms.EmailField(required=True) captcha = CaptchaField(error_messages={'invalid': '验证码错误'})
在后台逻辑加上form验证
... from .forms import LoginForm, RegisterForm, ForgetForm class ForgetPwdView(View): def get(self, request): forget_form = ForgetForm() return render(request, 'forgetpwd.html', {'forget_form': forget_form})
编辑forgetpwd.html
现在刷新忘记密码页面,验证码已经显示出来了
用户填写邮箱后需要发送邮件,编辑utrls.email_send.py
from random import Random from django.core.mail import send_mail from users.models import EmailVerifyRecord from mxonline.settings import EMAIL_FROM def random_str(randomlength=8): """生成随机字符""" str = '' chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' length = len(chars) - 1 random = Random() for i in range(randomlength): str += chars[random.randint(0, length)] return str def sendEmail(email, send_type='register'): email_record = EmailVerifyRecord() code = random_str(16) email_record.code = code email_record.email = email email_record.send_type = send_type email_record.save() if send_type == 'register': email_title = '慕学在线网激活链接' email_body = '请点击下面的链接激活你的账号:http://127.0.0.1:8000/active/{0}'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass elif send_type == 'forget': email_title = '慕学在线网密码重置' email_body = '请点击下面的链接重置你的密码:http://127.0.0.1:8000/reset/{0}'.format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass
在templates目录下创建一个邮件发送成功后跳转的页面send_success.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>邮件发送成功</title> </head> <body> <p>邮件已经发送成功,请注意查收!</p> </body> </html>
完善后台逻辑
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', '') user = UserProfile.objects.filter(email=email) if user: sendEmail(email, 'forget') return render(request, 'send_success.html') else: return render(request, 'forgetpwd.html', {'forget_form': forget_form, 'msg': '用户不存在'}) else: return render(request, 'forgetpwd.html', {'forget_form':forget_form})
再修改下前面页面,添加错误信息显示
启动服务,测试找回密码,收到邮件
[重置密码]
最后,还需要写一个重置密码的接口:用户点击重置密码连接后的动作
把重置密码页面password_reset.html拷贝到templates目录下
编辑users.views.py,写一个处理重置密码的类
class ResetPwdView(View): def get(self, request, reset_code): all_records = EmailVerifyRecord.objects.filter(code=reset_code) if all_records: for record in all_records: email = record.email #获取是哪个用户的链接 return render(request, 'password_reset.html', {'email': email}) else: return render(request, 'reset_fail.html') return render(request, 'login.html')
在templates创建一个重置密码失败的页面reset_fail.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>重置密码失败</title> </head> <body> <p>该链接无效!</p> </body> </html>
编辑urls.py配置一条重置密码的url
from users.views import ResetPwdView ... urlpatterns = [ url(r'^reset/(?P<reset_code>.*)/$', ResetPwdView.as_view(), name='reset_pwd'), ]
编辑password_reset.html,添加一个隐藏的input ,这个input的值就是email
现在访问发送到邮箱的重置密码连接,会跳转到重置密码页面
查看网页源码,可以发现之前我们添加的隐藏的input,这样到时提交把这个值传到后台就知道修改哪个账户的密码了
接下来做用户提交后的逻辑
编辑users.form.py来写一个form对重置密码的表单进行验证
class ResetPwdForm(forms.Form): pwd = forms.CharField(required=True, min_length=6) repwd = forms.CharField(required=True, min_length=6)
编辑users.view.py写提交的逻辑
class ModifyPwdView(View): def post(self, request): resetpwd_form = ResetPwdForm(request.POST) if resetpwd_form.is_valid(): pwd = request.POST.get('pwd', '') repwd = request.POST.get('repwd', '') email = request.POST.get('email', '') if pwd == repwd: user = UserProfile.objects.get(email=email) user.password = make_password(repwd) user.save() return render(request, 'login.html') else: return render(request, 'password_reset.html', {'msg':'密码不一致'}) else: return render(request, 'password_reset.html', {'resetpwd_form':resetpwd_form})
添加一个提交的url
... from users.views import ModifyPwdView urlpatterns = [ url(r'modifypwd/$', ModifyPwdView.as_view(), name='modify_pwd'), ]
编辑password_reset.html
现在可以重置密码了,修改完成后会跳转到登录页面