Django项目实战 - 重置密码功能

时间:2024-02-24 07:29:18

本章重点:

1. 需要用到两个html页面:  忘记密码.html    重置密码.html

2. 每个页面都有一个Form表单,因此需要在forms.py中创建两个类: ForgetPwdForm ModifyPwdForm

3. 需要创建三个url: forgeturl, reseturl, modifyurl

4. 需要在Views.py中创建三个View: ForgetPwdView, ResetView, ModifyPwdView

  有疑问的地方是,为什么需要创建三个url,和三个view,是因为:

  ResetView 负责get方法,Resetview接收url中的code到数据库取出对应的用户email,然后回传到html页面中。

  ModifyPwdView 负责post方法,需要从html页面中取出用户email和密码,然后提交给后台数据库保存。

5. Django要求user表中的密码时需要加密的,否则无法登录,因此需要用到make_password这个函数来对密码进行加密:

  from django.contrib.auth.hashers import make_password

下面是详细代码:

forms.py中创建的两个 Form

class ForgetPwdForm(forms.Form):
    email = forms.EmailField(required=True)
    captcha = CaptchaField(error_messages={"invalid": u"验证码错误"})


class ModifyPwdForm(forms.Form):
    password1 = forms.CharField(required=True, min_length=6)
    password2 = forms.CharField(required=True, min_length=6)

 

views.py中创建的三个view

class ForgetPwdView(View):
    def get(self, request):
        forget_form = ForgetPwdForm()
        return render(request, "forgetpwd.html", {"forget_form": forget_form})

    def post(self, request):
        forget_form = ForgetPwdForm(request.POST)
        if forget_form.is_valid():
            email = request.POST.get("email", "")
            send_register_email(email, "forget")
            return render(request, "send_success.html")
        else:
            return render(request, "forgetpwd.html", {"forget_form": forget_form})


class ResetView(View):
    """
    密码重置功能
    """

    def get(self, request, active_code):
        all_records = EmailVerifyRecord.objects.filter(code=active_code)
        if all_records:
            for record in all_records:
                email = record.email
                return render(request, "password_reset.html", {"email": email})
        else:
            return render(request, "active_fail.html")
        return render(request, "login.html")


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": u"密码不一致"})
            user = UserProfile.objects.get(email=email)
            user.password = make_password(pwd1)
            user.save()
            return render(request, "login.html")
        else:
            email = request.POST.get("email", "")
            return render(request, "password_reset.html", {"email": email, "modify_form": modify_form})

 

urls.py中配置的三个url

    url(r\'^forget/$\', ForgetPwdView.as_view(), name="forget_pwd"),
    url(r\'^reset/(?P<active_code>.*)/$\', ResetView.as_view(), name="reset_pwd"),
    url(r\'^modify_pwd/$\', ModifyPwdView.as_view(), name="modify_pwd"),

 

forgetpwd.html

<form id="jsFindPwdForm" method="post" action="{% url "forget_pwd" %}" autocomplete="off">
    <div class="form-group marb20 {% if forget_form.errors.email %}errorput{% endif %}">
        <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
        <input type="text" id="account" name="email" value="{{ forget_form.email.value }}" placeholder="邮箱" />
    </div>
    <div class="form-group captcha1 marb38">
        <label>&nbsp;&nbsp;</label>
        {{ forget_form.captcha }}
    </div>
    <div class="error btns" id="jsForgetTips">{% for key,error in forget_form.errors.items %}{{ error }}{% endfor %}</div>
    <input type="hidden" name="sms_type" value="1">
    <input class="btn btn-green" id="jsFindPwdBtn" type="submit" value="提交" />
    <p class="form-p" style="bottom:40px;">您还可以<a href="{% url "login" %}"> [直接登录]</a></p>
{% csrf_token %}
</form>

 

password_reset.html

需要注意的是创建了一个 hidden type的 input,用来ResetView将用户的email传递到页面中,ModifyPwdView来取用户的email.

<form id="reset_password_form" action="{% url "modify_pwd" %}" method="post">
    <ul>
        <li>
            <span class="">新 密 码 :</span>
            <input type="password" name="password1" id="pwd" placeholder="6-20位非中文字符">
            <i></i>
        </li>
        <input type="hidden" name="email" value="{{ email }}">
        <li>
            <span class="">确定密码:</span>
            <input type="password" name="password2" id="repwd" placeholder="6-20位非中文字符">
            <i></i>
        </li>
        <li class="button">
            <input type="submit" value="提交">
        </li>
    </ul>
{% csrf_token %}
</form>