Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding the password reset to Django Admin goes to a wrong URL?

Tags:

django

I'm following the section on Adding a password reset feature to the Django Admin, which asks you to add these four paths:

path('admin/password_reset/', auth_views.PasswordResetView.as_view(), name='admin_password_reset'),
path('admin/password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),

When I add them, the "Forgotten your password or username?" link appears on the Django Admin log in screen, and if I click it, it works, it even sends the email, but after the email, I end up with this error.

Page not found (404)
Request Method: GET
Request URL:    http://localhost:8000/accounts/password_reset/done/
Raised by:  django.contrib.auth.views.PasswordResetDoneView

404... well... yes... that's not where password_reset/done is. And the link in the email is for: http://localhost:8000/accounts/reset/Mjk/5...9, so, against, that's not where reset/<uidb64>/<token>/. Why are these URLs in the wrong place, /accounts/ instead of /admin/.

My full URL patterns look like this:

urlpatterns = [
    path('admin/password_reset/', auth_views.PasswordResetView.as_view(), name='admin_password_reset'),
    path('admin/password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
    path('admin/', admin.site.urls),
    path('accounts/', include('django.contrib.auth.urls')),
    path("", views.index, name="homepage")
]

I'm guessing then that those redirects go to /accounts/ because of this path('accounts/', include('django.contrib.auth.urls')), is that correct? is there another way of controlling them? I'm mostly trying to understand what's going on.

like image 1000
pupeno Avatar asked Dec 01 '25 13:12

pupeno


1 Answers

To send a password reset email containing another URL, I believe you need to add a separate email template. And to do that, you'll need to create a different view that links to that template. You can use Django's auth views by subclassing them and only define the settings you need to be different.

Here's how to create a custom password reset view generally, which can be used alongside the default one:

# urls.py

from .views import CustomPasswordResetView

urlpatterns = [
    ...
    # URL to submit your email address for reset link
    path('admin/password-reset', CustomPasswordResetView.as_view(), name='custom_password_reset'),
    # URL link in email, lands on password reset form
    path('admin/reset/<uidb64>/<token>/', CustomPasswordResetConfirmView.as_view(), name='custom_password_reset_confirm'),
    ...
]

# views.py

from django.contrib.auth.views import PasswordResetView

class CustomPasswordResetView(PasswordResetView):
    email_template_name = 'registration/custom_password_reset_email.html'

By default, Django uses the password reset email template in django/contrib/admin/templates/registration/password_reset_email.html. The default HTML templates relating to password resets are there too.

To specify your own template, create another registration directory somewhere in your project templates (e.g. users/templates/registration/ and create the file there. Make sure to give it a different name from Django's default templates, e.g. registration/custom_password_reset_email.html, then copy and paste the default email text into it, and change the named URL to the one you want, i.e. {% 'custom_password_reset_confirm' %}.

You can subclass the other relevant views (PasswordChange, PasswordChangeDone etc.) to override other default settings as needed, such as HTML template, form class and redirect URL. All the password reset views are in django.contrib.auth.views. The auth views are provided as class-based views (alongside the older standard function-based views, which were removed as of Django version 2.1).

like image 174
birophilo Avatar answered Dec 04 '25 04:12

birophilo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!