Im trying to implement Reset Password View by using View
class.
Actually I faced with an error that is annoying.
I have 3 Views for implementing:
UserResetPasswordView
Here User enters email and a request sends to his/her emailUserResetPasswordRequestSentView
Here shows a message that email has sentUserResetPasswordConfirm
after 2 views above, this view let's the user change password.
after redirecting user to UserResetPasswordRequestSentView
, an email will be send to the user's email to access the user to change his/her password.
so user will be redirect to UserResetPasswordConfirm
that contains inputs for setting new password.
This is my urls.py
script:
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',
),
]
this is UserResetPasswordView
view:
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,
},
)
this is the form that user can set 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,
},
)
this is the form
that contains inputs to set new password for user:
{% 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 %}
here the user should open the link that sent by email but everytime I try to redirect user to UserResetPasswordConfirm
, django shows me this error:
I would be really thankful if you help me.
Render with the
uidb64
andtoken
, so:and then in the view use these to determine the URL: