提问人:Shervin.bdn 提问时间:10/16/2023 更新时间:10/16/2023 访问量:23
/reset-password-confirm/ 中的 NoReverseMatch
NoReverseMatch at /reset-password-confirm/
问:
我正在尝试使用类实现重置密码视图。
实际上,我遇到了一个令人讨厌的错误。View
我有 3 个实现视图:
UserResetPasswordView
在这里,用户输入电子邮件,请求发送到他/她的电子邮件UserResetPasswordRequestSentView
此处显示电子邮件已发送的消息UserResetPasswordConfirm
在上面的 2 个视图之后,此视图让用户更改密码。
将用户重定向到 后,将向用户的电子邮件发送一封电子邮件,以访问用户更改他/她的密码。UserResetPasswordRequestSentView
因此,用户将被重定向到包含用于设置新密码的输入。UserResetPasswordConfirm
这是我的脚本:urls.py
urlpatterns = [
path(
route='reset-password',
view=views.UserResetPasswordView.as_view(),
name='reset',
),
path(
route='reset-password-request-sent',
view=views.UserResetPasswordRequestSentView.as_view(),
name='reset_sent',
),
path(
route='reset-password-confirm/<uidb64>/<token>',
view=views.UserResetPasswordConfirm.as_view(),
name='reset_confirm',
),
]
这是视图:UserResetPasswordView
class UserResetPasswordView(View):
def get(self, request: HttpRequest) -> HttpResponse:
reset_password_form: ResetPasswordForm = ResetPasswordForm()
return render(
request=request,
template_name='reset/reset.html',
context={
'reset_password_form': reset_password_form,
},
)
def post(self, request: HttpRequest) -> Union[HttpResponseRedirect, HttpResponsePermanentRedirect, HttpResponse]:
reset_password_form: ResetPasswordForm = ResetPasswordForm(request.POST or None)
if (reset_password_form.is_valid()):
cd = reset_password_form.cleaned_data
user = get_user_model().objects.filter(Q(email=cd['email'])).first()
if (user):
subject = 'درخواست بازنشانی رمز ورود'
message = render_to_string(
template_name='email/template_reset_password.html',
context={
'user': user,
'domain': get_current_site(request=request).domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
'protocol': 'https' if request.is_secure() else 'http',
}
)
send_mail(
subject,
message,
'settings.EMAIL_HOST_USER',
[cd['email']],
fail_silently=False
)
return redirect(to=reverse('reset_sent'))
else:
return redirect(to=reverse('reset'))
return render(
request=request,
template_name='reset/reset.html',
context={
'reset_password_form': reset_password_form,
},
)
这是用户可以设置 new password() 的形式:UserResetPasswordConfirm
class UserResetPasswordConfirm(View):
def get(self, request: HttpRequest, uidb64, token) -> HttpResponse:
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user_obj = User.objects.get(pk=uid)
except:
user_obj = None
if (user_obj is not None and account_activation_token.check_token(user_obj, token)):
form: ResetPasswordConfirmForm = ResetPasswordConfirmForm()
else:
messages.error(
request=request,
message='توکن شما منقضی شده است',
)
return render(
request=request,
template_name='reset/reset-confirm.html',
context={
'form': form,
},
)
def post(self, request: HttpRequest, uidb64, token) -> Union[HttpResponseRedirect, HttpResponsePermanentRedirect, HttpResponse]:
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user_obj = User.objects.get(pk=uid)
except:
user_obj = None
if (user_obj is not None and account_activation_token.check_token(user_obj, token)):
form: ResetPasswordConfirmForm = ResetPasswordConfirmForm(request.POST or None)
if (form.is_valid()):
cd = form.cleaned_data
if (cd['new_password'] != cd['con_new_password']):
form.add_error(
field='new_password',
error='رمز ورود شما با یکدیگر مطابقت ندارد',
)
else:
user_obj.set_password(raw_password=cd['new_password'])
user_obj.save()
return redirect(to=reverse('reset_complete'))
else:
form.add_error(
field='new_password',
error='رمز ورود شما با یکدیگر مطابقت ندارد',
)
return render(
request=request,
template_name='reset/reset-confirm.html',
context={
'form': form,
},
)
else:
messages.error(
request=request,
message='توکن شما منقضی شده است',
)
return render(
request=request,
template_name='reset/reset-confirm.html',
context={
'form': form,
},
)
这是包含为用户设置新密码的输入:form
{% extends "base.html" %}
{% load static %}
{% block title %}
<title>
تنظیم رمز ورود جدید
</title>
{% endblock %}
{% block body %}
<div class="container text-center mt-5">
<form class="form-inline" action="{% url 'reset_confirm' %}" method="post">
{% csrf_token %}
<div class="row">
<h6 class="text-info mt-2">رمز ورود جدید حداقل بین 8 تا 64 کاراکتر (ترکیب حروف و اعداد)</h6>
<div class="field">
<p class="control has-icons-left">
{{ form.new_password }}
<span class="icon is-small is-left">
<i style="color: #1F2330;" class="fas fa-lock"></i>
</span>
</p>
</div>
<h6 class="text-info mt-2">تایید مجدد رمز ورود جدید</h6>
<div class="field">
<p class="control has-icons-left">
{{ form.con_new_password }}
<span class="icon is-small is-left">
<i style="color: #1F2330;" class="fas fa-lock"></i>
</span>
</p>
</div>
</div>
<div class="row">
<div class="col">
<button style="width: 150px;" id="set_pass" type="submit" class="btn btn-info text-dark">ارسال درخواست</button>
</div>
</div>
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
jQuery(function($){
$(document).ajaxSend(function() {
$('spinner-border').fadeIn(580);
var loading_tag = '<div class="spinner-border"></div>  لطفا صبر کنید';
$('#set_pass').html(loading_tag);
});
$('#set_pass').click(function() {
$.ajax({
type: 'GET',
success: function(data) {
console.log(data);
}
}).done(function() {
setTimeout(function() {
$('.spinner-border').fadeOut(500);
}, 700);
});
});
});
</script>
{% endblock %}
在这里,用户应该打开通过电子邮件发送的链接,但每次我尝试将用户重定向到时,django 都会向我显示此错误:UserResetPasswordConfirm
如果你帮助我,我将不胜感激。
答:
1赞
willeM_ Van Onsem
10/16/2023
#1
使用 和 进行渲染,因此:uidb64
token
class UserResetPasswordConfirm(View):
def get(self, request: HttpRequest, uidb64, token) -> HttpResponse:
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user_obj = User.objects.get(pk=uid)
except:
user_obj = None
if user_obj is not None and account_activation_token.check_token(
user_obj, token
):
form: ResetPasswordConfirmForm = ResetPasswordConfirmForm()
else:
messages.error(request=request, message='توکن شما منقضی شده است')
return render(
request=request,
template_name='reset/reset-confirm.html',
context={'form': form, 'uidb64': uidb64, 'token': token},
)
# …
然后在视图中使用以下命令来确定 URL:
<form class="form-inline" action="{% url 'reset_confirm' uidb64 token %}" method="post">
注意:
重定向(...)
[Django-文档]通常采用视图的名称和(可选)kwargs,因此不应使用reverse(...)
[Django-doc]。因此,您可能希望重写为 .redirect(redirect('reset_complete'))
redirect('reset_complete')
注意:通常不需要直接对类进行子类化。在本例中,你的视图看起来像一个
FormView
[Django-doc]。通过使用 a 而不是 simple ,您通常不必实现大量样板代码。View
FormView
View
评论
app_name = ...
urls.py