Trilla
Trilla

Reputation: 771

Django password_reset/done page overriding my custom URL

I am working on the password reset area of my registration using custom html so am overriding Django's password reset pages.

The reset password initial link works fine and redirects to my custom URL:

/account/reset-password/

There a user can enter their email address and click submit to receive a password reset email. The next page shown should be

/account/reset-password/done/

However when they click submit, I can see from the command line:

POST /account/reset-password/ HTTP/1.1" 302 0
GET /password_reset/done/ HTTP/1.1" 302 0
GET /account/login/ HTTP/1.1" 200 2237

The 2nd line should be going to

/account/reset-password/done/

not

/password_reset/done/

urls.py

app_name='accounts'
from django.conf.urls import url
from . import views
from django.contrib.auth.views import LoginView, LogoutView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^login/$', LoginView.as_view(template_name='accounts/login.html'), name='login'),
    url(r'^logout/$', LogoutView.as_view(template_name='accounts/logout.html'), name='logout'),
    url(r'^register/$', views.register, name='register'),
    url(r'^profile/$', views.view_profile, name='view_profile'),
    url(r'^profile/edit$', views.edit_profile, name='edit_profile'),
    url(r'^change-password/$', views.change_password, name='change_password'),

    url(r'^reset-password/$',
    PasswordResetView.as_view(template_name='accounts/reset_password.html'),
    {'post_reset_redirect': 'accounts:reset_password_done',
    'email_template_name': 'accounts/reset_password_email.html'},
    name='reset_password'),

    url(r'^reset-password/done/$',
    PasswordResetDoneView.as_view(template_name='accounts/reset_password_done.html'),
    name='reset_password_done'),

    url(r'^reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>,+)/$',
    PasswordResetConfirmView.as_view(template_name='accounts/reset_password_confirm.html'),
    name='reset_password_confirm'),

    url(r'^reset-password/complete/$',
    PasswordResetConfirmView.as_view(template_name='accounts/reset_password_complete.html'),
    name='reset_password_complete'),

]

settings.py

INSTALLED_APPS = [
    'accounts',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

middleware.py

import re

from django.conf import settings
from django.urls import reverse
from django.shortcuts import redirect
from django.contrib.auth import logout

EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [re.compile(url) for url in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        assert hasattr(request, 'user')
        path = request.path_info.lstrip('/')
        url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)

        if path == reverse('accounts:logout').lstrip('/'):
            logout(request)

        if request.user.is_authenticated and url_is_exempt:
            return redirect(settings.LOGIN_REDIRECT_URL)
        elif request.user.is_authenticated or url_is_exempt:
            return None
        if not request.user.is_authenticated and url_is_exempt:
            return None
        else:
            return redirect(settings.LOGIN_URL)

Upvotes: 1

Views: 4182

Answers (1)

Pankaj Sharma
Pankaj Sharma

Reputation: 2277

You can set your success_url in PasswordResetView,

url(r'^reset-password/$',
    PasswordResetView.as_view(template_name='accounts/reset_password.html'),
    {
    'email_template_name': 'accounts/reset_password_email.html',
     'success_url' : reverse_lazy('accounts:reset_password_done')
     },
    name='reset_password'),

or you can directly pass success_url in .as_view()

 url(r'^reset-password/$',
        PasswordResetView.as_view(template_name='accounts/reset_password.html',
         email_template_name = 'accounts/reset_password_email.html',
         success_url = reverse_lazy('accounts:reset_password_done'))  ,
         name='reset_password'),

Upvotes: 5

Related Questions