Django PasswordResetDoneView 未找到视图或 URL 模式

Django PasswordResetDoneView Not Finding View or URL Pattern

我一直在为 Django 应用构建用户帐户功能。在这样做的过程中,我遇到了一个问题,不确定是我做错了什么还是遇到了 Django/Python 的不熟悉的怪癖。感谢任何帮助。

我有以下一组(工作)网址(user_accounts/urls.py):

app_name = 'user_accounts'
urlpatterns = [
    path('signup', views.UserSignUpView.as_view(), name='signup'),
    path('logout', auth_views.LogoutView.as_view(), name='logout'),
    path('login', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),

    re_path(r'^reset/$', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset'),

    re_path(r'^reset/done/$', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),

    re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),

    re_path(r'^reset/complete/$', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]

我一直在尝试测试如下(user_accounts/tests/test_views_forms.py):

class SuccessfulPasswordResetTests(TestCase):
    def setUp(self):
        email = 'jon@doe.com'
        User.objects.create_user(username='john', email=email, password='123abcdef')
        url = reverse('user_accounts:password_reset')
        print(reverse('user_accounts:password_reset_done'))
        self.response = self.client.post(url, {'email': email})

    def test_redirection(self):
        '''
        A valid form submission should redirect to password_reset_done
        '''
        url = reverse('password_reset_done')
        self.assertRedirects(self.response, url)

问题是我收到以下错误:

File "/home/user-name/sites/project-web/project/user_accounts/tests/test_views_forms.py", line 128, in setUp self.response = self.client.post(url, {'email': email})

django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_done' not found. 'password_reset_done' is not a valid view function or pattern name.

然而,当我在浏览器中直接导航到 /user/reset/done/ 时,它提供了正确的模板。

项目的 urls.py 文件如下所示。请注意,我使用的是 DjangoCMS

from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('video/', include('video_uploader.urls')),
    path('user/', include('user_accounts.urls')),
    path('', include('cms.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

您只需在 PasswordResetView 中设置 success_url 属性。 defaults to reverse_lazy('password_reset_done') 开箱即用,但由于您使用的是自定义应用程序名称,因此即使名称空间相同,url 也无法解析。

这应该可以解决问题:

re_path(r'^reset/$', auth_views.PasswordResetView.as_view(
    template_name='user_accounts/password_reset.html',
    <b>success_url=reverse_lazy('user_accounts:password_reset_done'),</b>
    email_template_name='user_accounts/password_reset_email.html',
    subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset')

这是一个工作代码。请注意在几个路径中添加 success_url ,它们最终作为级联工作。那是一个接一个被触发。我还从正则表达式格式转换为路径格式。这可能也是让事情正常工作所需要的。

from django.urls import path, re_path, reverse_lazy, include
from django.contrib.auth import views as auth_views
from . import views

app_name = 'user_accounts'
urlpatterns = [
    path('signup/', views.UserSignUpView.as_view(), name='signup'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
    path('login/', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),

    path('password-change/', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt',  success_url = reverse_lazy('user_accounts:password_reset_done')), name='password_reset'),

    path('password-change/done/', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),

    #re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),

    path('password-change/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html', success_url = reverse_lazy('user_accounts:password_reset_complete')), name='password_reset_confirm'),

    path('password-change/complete/', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]