我有一个带角度前端的django应用程序。当我从前端尝试发送passwordReset请求时,我收到以下错误:
使用参数'()'和关键字反转'password_reset_confirm' 参数'{u'uidb64':'MTE',u'token':u'3z4-eadc7ab3866d7d9436cb'}' 未找到。尝试了0种模式:[]
它的POST请求转到http://127.0.0.1:8080/rest-auth/password/reset/
以下是我的urls.py的样子:
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
url(r'^account/', include('allauth.urls'))
)
答案 0 :(得分:24)
我也遇到了这个问题,发现这个github issue它说我们需要添加
url(r'^', include('django.contrib.auth.urls')),
在urlpatterns上。
如上所述,它说PasswordReset视图取决于django.contrib.auth.views.password_reset_confirm
视图。
答案 1 :(得分:5)
正如Roar Skullestad指出的那样,问题出在默认的电子邮件模板上,该模板试图通过reversing视图名“ password_reset_confirm”来解析URL,该URL未定义。
使用自定义路由注册视图名称“ password_reset_confirm”就足够了,然后默认的电子邮件模板呈现将正常工作。
您可以通过向urls.py添加路径来使用自定义路由注册视图名称:
urlpatterns = [
...,
path('password-reset/<uidb64>/<token>/', empty_view, name='password_reset_confirm'),
]
密码重置-自定义路由,该密码重置确认视图。如果您有SPA(Angular),它将是您的SPA视图的URL(例如到Angular组件的路由),将处理密码重置。
这是将解析并嵌入到电子邮件中的URL。对于此示例,它将类似于:
http://my-spa.com/app-name/password-reset/Nw/51v-490d4b372ec930e49049/
empty_view -对于SPA(Angular),您实际上不需要服务器端实现,因为前端实际上会处理此路由。我使用了视图的这种实现,但是可以是其他任何形式:
from django.http import HttpResponse
def empty_view(request):
return HttpResponse('')
由于我使用的是Angular,这是我的Angular组件的路由:
{
path: 'password-reset/:uid/:token',
component: PasswordRecoveryComponent
}
答案 2 :(得分:4)
对我来说,问题是site-packages / django / contrib / admin / templates / registration / password_reset_email.html中的这一行:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
根据我的理解,问题是由在contrib / auth / urls.py中反向查找不适用于此行引起的:
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
'django.contrib.auth.views.password_reset_confirm',
name='password_reset_confirm'),
我的(至少是暂时的)解决方案是覆盖模板并硬编码电子邮件中链接的URL的反向查找部分。
新模板的路径在settings.py中指定:
TEMPLATE_DIRS =(
"/absolute/path/to/my/templates/directory",
)
由于我使用的是角度前端,我还更改了链接,以便通过角度客户端触发密码重置确认:
{{ protocol }}://{{ domain }}/#/passwordResetConfirm/{{ uid }}/{{ token }}
答案 3 :(得分:3)
@ AbimaelCarrasquillo的解决方案有效,但您可能不希望将这些端点公开为评论中提到的@dpstart。
我通过覆盖rest-auth
的PasswordResetSerializer并简单地替换重置形式来解决这个问题:
password_reset_form_class = PasswordResetForm
从内部django.contrib.auth.forms.PasswordResetForm
到allauth.account.forms.ResetPasswordForm
确保将以下内容添加到您的设置中:
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':'path.to.PasswordResetSerializer'
}
答案 4 :(得分:1)
嗯,我也遇到了这个问题。每次我输入电子邮件并按下按钮时,它都会将我带到 NoReverseMatch 网址,我正在使用:
re_path(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),name='password_reset_confirm')
(不再使用 django 中的 url 匹配正则表达式,而是使用 re_path)
我的解决方案是稍微更改正则表达式,因为 “csrf 令牌” 的长度超过 20 个字 - 这就是我收到错误的原因,您应该尝试相同的方法。
re_path(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,40})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),
name='password_reset_confirm')
您可以使用 +
(在正则表达式中表示一个或多个)或 {1,40}
(在正则表达式中表示匹配从 1 到 40)
答案 5 :(得分:0)
将此项添加到项目url.py文件
url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
url('', include('social.apps.django_app.urls', namespace='social')),
答案 6 :(得分:0)
查看FAQ:它说明了此错误以及如何解决。它会将您引向演示程序,其中包含:
# this url is used to generate email content
url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
TemplateView.as_view(template_name="password_reset_confirm.html"),
name='password_reset_confirm'),
答案 7 :(得分:0)
对于那些仍在为这个问题苦苦挣扎的人,我发现反向查找内部视图在核心项目url中而不是在任何应用程序中查找反向查找。它可以在应用程序中进行一些调整,但我不确定。但是它可以直接在核心项目urls.py
上创建重置URL。{ 路径(r'password_reset /',PasswordResetView.as_view(template_name ='password_reset_form.html'),name ='password_reset'), 路径(r'password_reset_done /',PasswordResetDoneView.as_view(template_name ='password_reset_done.html'),name ='password_reset_done'), 路径(r'password_reset_confirm ///',PasswordResetConfirmView.as_view(template_name ='password_reset_confirm.html'),name ='password_reset_confirm'), 路径(r'password_reset_complete /',PasswordResetCompleteView.as_view(template_name ='password_reset_complete.html'),name ='password_reset_complete'), }
答案 8 :(得分:0)
我的解决方案是覆盖调用“ password_reset_confirm”相反的电子邮件模板。确保电子邮件模板使用URL中的UID和令牌将URL发送到您的前端应用程序(而不是尝试撤消“ password_reset_confirm”)。
您的前端路由应采用URL,先进行解析,然后使用更新的用户密码,然后将其作为API调用发送回后端以进行确认。
答案 9 :(得分:0)
我通过移动这些按钮解决了这个问题:
path('reset_password/', auth_views.PasswordResetView.as_view(), name='password_reset'),
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset_password_sent/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset_password_complete/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
从 accounts / urls.py 到 yourProjectName / urls.py 。
我猜是path('', include("accounts.urls")),
引起了问题。
答案 10 :(得分:0)
我有一个无头后端,因此仅添加或重命名URL并不是一个好的选择。 问题出在电子邮件模板上,您可以覆盖它。只要注意您在设置上的正确路径即可。 就我而言,我在用户应用程序中拥有所有这些逻辑。所以我有这样的东西。
users/templates/registration/password_reset_email.html
在此模板中,我有一条新的自定义消息,没有反向URL调用。 如果您不仅需要覆盖模板,还需要向模板发送其他数据。您还必须覆盖串行器。为此,您必须创建新的序列化器
from dj_rest_auth.serializers import PasswordResetSerializer as RestPasswordResetSerializer
class PasswordResetSerializer(RestPasswordResetSerializer):
def get_email_options(self):
return {
'html_email_template_name': 'registration/password_reset_email_html.html', # if you want to use an HTML template you can declare here
'extra_email_context': {'custom_key': 'custom value for my template',}
}
并添加到设置。
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':'path.to.PasswordResetSerializer'
}
在序列化程序上,您还可以根据需要添加自定义验证。
答案 11 :(得分:0)
在你的views.py中,如果你设置了一个token,把它和类似的路径一起传递:
path('resetpassword_validate/<uidb64>/<token>/', views.resetpassword_validate, name='resetpassword_validate'),