Django PasswordResetDoneView does not redirect to login

Viewed 37

I have a reset password procedure, here are the codes:

Password Reset Request:

<form method="POST">
{% csrf_token %}
    <div class="wrap-input100 validate-input input-group" data-bs-validate="Format email valide requis: ex@abc.xyz">
        <a class="input-group-text bg-white text-muted">
            <i class="zmdi zmdi-email text-muted" aria-hidden="true"></i>
        </a>
        <input id="id_email" class="input100 border-start-0 form-control ms-0" type="email" placeholder="Email" name="email" autocomplete="email" maxlength="254">
    </div>                  
    <button class="btn btn-primary" type="submit">Envoyer le lien de réinitialisation</button>
</form>

Password Reset Confirmation:

<form method="POST">
{% csrf_token %}
    <div class="wrap-input100 validate-input input-group" id="Password-toggle">
        <a class="input-group-text bg-white text-muted">
            <i class="zmdi zmdi-eye text-muted" aria-hidden="true"></i>
        </a>
        <input class="input100 border-start-0 form-control ms-0" type="password" placeholder="Nouveau mot de passe" id="id_new_password1" name="new_password1">
    </div>
    <div class="wrap-input100 validate-input input-group" id="Password-toggle">
        <a class="input-group-text bg-white text-muted">
            <i class="zmdi zmdi-eye text-muted" aria-hidden="true"></i>
        </a>
        <input class="input100 border-start-0 form-control ms-0" type="password" placeholder="Confirmation du nouveau mot de passe" id="id_new_password2" name="new_password2">
    </div>
    <div class="container-login100-form-btn">
        <button class="login100-form-btn btn-primary" type='submit'>Réinitialiser</button>
    </div>
 </form>

Password Reset View:

def password_reset_request(request):
    if request.method == "POST":
        password_reset_form = PasswordResetForm(request.POST)
        if password_reset_form.is_valid():
            data = password_reset_form.cleaned_data["email"]
            associated_users = Account.objects.filter(Q(email=data))
            if associated_users.exists():
                for user in associated_users:
                    subject = "Demande de changement de mot de passe"
                    email_template_name = "core/email/password_reset_email.txt"
                    c = {
                        "email": user.email,
                        "domain": EMAIL_DOMAIN,
                        "site_name": "XXXXXX.XXXX",
                        "uid": urlsafe_base64_encode(force_bytes(user.pk)),
                        "user": user,
                        "token": account_activation_token.make_token(user),
                        "protocol": EMAIL_PROTOCOL,
                    }
                    email = render_to_string(email_template_name, c)
                    try:
                        send_mail(
                            subject,
                            email,
                            "info@XXXXXX.XXXX",
                            [user.email],
                            fail_silently=False,
                        )
                    except BadHeaderError:
                        return HttpResponse("Invalid header found.")
                    return redirect("password_reset_done")

    password_reset_form = PasswordResetForm()
    return render(
        request=request,
        template_name="core/pwdreset/password_reset.html",
        context={"password_reset_form": password_reset_form},
    )

Password Reset URLs:

path("password_reset/", password_reset_request, name="password_reset"),
    path(
        "password_reset/done/",
        auth_views.PasswordResetDoneView.as_view(
            template_name="core/pwdreset/password_reset_done.html"
        ),
        name="password_reset_done",
    ),
    path(
        "reset/<uidb64>/<token>/",
        auth_views.PasswordResetConfirmView.as_view(
            template_name="core/pwdreset/password_reset_confirm.html"
        ),
        name="password_reset_confirm",
    ),
    path(
        "reset/done/",
        auth_views.PasswordResetCompleteView.as_view(
            template_name="core/pwdreset/password_reset_complete.html"
        ),
        name="password_reset_complete",
    ),

Settings:

[...]
AUTH_USER_MODEL = "core.Account"

LOGIN_REDIRECT_URL = "dashboard"
LOGOUT_REDIRECT_URL = "index"
LOGIN_URL = "login"
LOGOUT_URL = None
[...]

When I enter the new password and the confirmation, the page resets, and it does not redirect to any other page nor confirm whether the password was changed or not?

I followed many tutorials that use the django.contrib.auth and this does not seem to work.

2 Answers

You redirect when the email is sent successfully. But immediatly after that you rerender the empty form and return render(..) again. So your code does exactly what you wrote, but thats not what you want.

You have not prescribed a redirect for if password_reset_form.is_valid():

def password_reset_request(request):
    if request.method == "POST":
        password_reset_form = PasswordResetForm(request.POST)
        if password_reset_form.is_valid():
            data = password_reset_form.cleaned_data["email"]
            associated_users = Account.objects.filter(Q(email=data))
            if associated_users.exists():
                for user in associated_users:
                    subject = "Demande de changement de mot de passe"
                    email_template_name = "core/email/password_reset_email.txt"
                    c = {
                        "email": user.email,
                        "domain": EMAIL_DOMAIN,
                        "site_name": "XXXXXX.XXXX",
                        "uid": urlsafe_base64_encode(force_bytes(user.pk)),
                        "user": user,
                        "token": account_activation_token.make_token(user),
                        "protocol": EMAIL_PROTOCOL,
                    }
                    email = render_to_string(email_template_name, c)
                    try:
                        send_mail(
                            subject,
                            email,
                            "info@XXXXXX.XXXX",
                            [user.email],
                            fail_silently=False,
                        )
                    except BadHeaderError:
                        return HttpResponse("Invalid header found.")
            return redirect("password_reset_done")
        else:
            password_reset_form = PasswordResetForm()
    return render(
        request=request,
        template_name="core/pwdreset/password_reset.html",
        context={"password_reset_form": password_reset_form},
    )
   
Related