You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django内置password_reset视图报错:找不到'reset_password'反向解析

Django Password Reset: Why Moving URLs to Main urls.py Fixes "Reverse for 'reset_password' not found" Error

I recently hit a frustrating issue while setting up Django's built-in password reset flow: after following tutorials to configure the password_reset views, accessing the corresponding URL kept throwing this error:

Reverse for 'reset_password' not found. 'reset_password' is not a valid view function or pattern name.

I tried several fixes with no luck—until I moved the password_reset and password_reset_confirm URL configurations from my app's urls.py to the project's root urls.py, which resolved the problem instantly. Let's break down the root causes and alternative solutions so you don't have to move your URLs if you don't want to.

Deep Dive into the Root Cause

The core issue boils down to URL namespace handling and how Django's built-in password reset views generate and resolve URLs:

  • Unaccounted-for Namespaces
    If you placed the password reset URLs inside a sub-app's urls.py and added a namespace when including the app's URLs in the root urls.py, Django expects all URL reversals for that app to include the namespace prefix. However, Django's default password reset views (and their associated email templates) generate URL reversals without specifying this namespace—so when it tries to find reset_password, it can't locate the version tucked away in your namespaced sub-app.

  • URL Resolution Scope
    Django resolves URLs starting from the root urls.py. When you include a sub-app's URLs with a namespace, those URLs are only visible within that namespace scope. The built-in views don't know to look inside your app's namespace when generating reset links or redirecting after actions like password reset submission.

  • Hardcoded Reverse Logic
    Under the hood, Django's PasswordResetView and related views use reverse() or reverse_lazy() with plain view names (like password_reset_done) without any namespace. If your URLs are in a namespaced sub-app, these calls fail because they're looking for a global URL pattern that doesn't exist.

Alternative Solutions (No Need to Move URLs to Root)

If you prefer keeping your password reset URLs organized in a sub-app, here are three workarounds:

1. Update Namespace References Everywhere

If you want to keep the URLs in your sub-app:

  • First, add an app_name to your sub-app's urls.py:
    # your_app/urls.py
    app_name = 'your_app'
    urlpatterns = [
        path('password-reset/', PasswordResetView.as_view(), name='password_reset'),
        path('password-reset/done/', PasswordResetDoneView.as_view(), name='password_reset_done'),
        # ... other password reset URLs
    ]
    
  • Include the app's URLs in the root urls.py with the namespace:
    # project/urls.py
    path('accounts/', include('your_app.urls', namespace='your_app'))
    
  • Update all URL reversals to include the namespace:
    • In your templates, change {% url 'password_reset' %} to {% url 'your_app:password_reset' %}
    • Customize Django's default password reset email template (copy it from django/contrib/admin/templates/registration/password_reset_email.html to your project's templates folder) and update the reset link to use the namespace:
      {% url 'your_app:password_reset_confirm' uidb64=uid token=token %}
      

2. Add a Namespace-Free Alias in Root urls.py

You can keep the URLs in your sub-app but add a "global" alias in the root urls.py so the built-in views can find them:

# project/urls.py
from your_app.urls import urlpatterns as password_reset_urls

urlpatterns += [
    path('accounts/', include(password_reset_urls)),
]

This creates a namespace-free version of the URLs that Django's built-in views can resolve without needing to specify a namespace.

3. Customize the Built-in Views to Use Your Namespace

Create custom subclasses of Django's password reset views, overriding the parts that generate URLs to include your namespace:

# your_app/views.py
from django.contrib.auth.views import PasswordResetView, PasswordResetDoneView
from django.urls import reverse_lazy

class NamespacedPasswordResetView(PasswordResetView):
    success_url = reverse_lazy('your_app:password_reset_done')

class NamespacedPasswordResetDoneView(PasswordResetDoneView):
    # Add custom behavior here if needed
    pass

Then use these custom views in your sub-app's urls.py:

# your_app/urls.py
app_name = 'your_app'
from .views import NamespacedPasswordResetView, NamespacedPasswordResetDoneView

urlpatterns = [
    path('password-reset/', NamespacedPasswordResetView.as_view(), name='password_reset'),
    path('password-reset/done/', NamespacedPasswordResetDoneView.as_view(), name='password_reset_done'),
    # ... other password reset URLs with custom views as needed
]

You'll still need to update template URL reversals to use the namespace, but this ensures the views themselves generate correct URLs.

内容的提问来源于stack exchange,提问作者CatalinC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:10:39