在使用 Django 1.6.5 中的 django.contrib.auth.views.password_reset 进行用户密码重置时,可能会遇到以下错误:
NoReverseMatch at /reset/Nw/3u5-5654a2cadfa432b86577/
Reverse for 'password_reset_complete' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
或者,当在 URL 中添加参数 name='password_reset_confirm' 时,可能会遇到以下错误:
A server error occurred. Please contact the administrator.
2、解决方案
要解决这些错误,需要进行以下修改:
-
在 URL 配置中,将
'django.contrib.auth.views.password_reset_confirm'的参数name='password_reset_confirm'从 URL 中删除:(r'^reset/(?P<uidb64>[0-9A-Za-z_-]+)/(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'), -
在视图函数中,将
password_reset_complete的参数name='password_reset_complete'从 URL 中删除:def password_reset_complete(request, reset_uidb64=None, token=None): """ Reset password complete. """ redirect_to = reverse('home') return password_reset_complete(request, extra_context={'redirect_to': redirect_to})
这样,就可以解决 NoReverseMatch 和服务器错误的问题。
代码例子
以下是一个完整的代码例子,展示了如何使用 Django 1.6.5 重置用户密码:
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import (
PasswordResetForm,
SetPasswordForm,
)
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import (
password_change,
password_reset,
password_reset_confirm,
password_reset_done,
)
from django.core.mail import send_mail
from django.shortcuts import redirect, render
def password_reset_request(request):
"""
Reset password request.
"""
if request.method == 'POST':
form = PasswordResetForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
user = User.objects.filter(email=email).first()
if user is not None:
token = default_token_generator.make_token(user)
send_mail(
'Password reset',
'Click here to reset your password: {}?uidb64={}&token={}'.format(
request.build_absolute_uri(reverse('password_reset_confirm')),
user.pk,
token)
from_email='noreply@example.com',
recipient_list=[email])
messages.success(request, 'An email has been sent to your email address.')
return redirect('home')
else:
form = PasswordResetForm()
return render(request, 'registration/password_reset_form.html', {'form': form})
def password_reset_done(request):
"""
Reset password done.
"""
return render(request, 'registration/password_reset_done.html')
def password_reset_confirm(request, uidb64=None, token=None):
"""
Reset password confirm.
"""
if uidb64 is not None and token is not None:
user = User.objects.get(pk=uidb64)
if default_token_generator.check_token(user, token):
return render(request, 'registration/password_reset_confirm_form.html', {'uidb64': uidb64, 'token': token})
return redirect('home')
def password_reset_complete(request):
"""
Reset password complete.
"""
redirect_to = reverse('home')
return password_reset_complete(request,
extra_context={'redirect_to': redirect_to})
@login_required
def change_password(request):
"""
Change password.
"""
if request.method == 'POST':
form = SetPasswordForm(request.user, request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your password has been changed.')
return redirect('home')
else:
form = SetPasswordForm(request.user)
return render(request, 'registration/change_password.html', {'form': form})
在上面的代码中,我们使用了 Django 内置的 PasswordResetForm 和 SetPasswordForm 来处理密码重置和修改,并使用了内置的视图函数来处理密码重置请求、完成密码重置、确认密码重置和修改密码。