• 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

    现在可以重置密码了,修改完成后会跳转到登录页面

  • 相关阅读:
    2010全球最值得模仿的230个网站 dodo
    IIS支持解析json dodo
    很好用的界面设计工具——Balsamiq dodo
    git本地分支目录和远程服务器的分支目录不一样的同步方法
    中新赛克——基于工业资产全息画像的工业互联网安全监测平台 规格严格
    解决redis requires ruby version 2.3.0[转载] 规格严格
    fpm包安装 规格严格
    git本地分支目录和远程服务器的分支目录不一样的同步方法[转】 规格严格
    MyBatis逆向工程generatorConfig配置文件的Table中generatedKey的作用[转载] 规格严格
    How to set character_set_database and collation_database to utf8 in my.ini 规格严格
  • 原文地址:https://www.cnblogs.com/sellsa/p/8463040.html
Copyright © 2020-2023  润新知