/重置密码确认/

问题描述 投票:0回答:1

我尝试使用

View
类来实现重置密码视图。 事实上,我遇到了一个令人烦恼的错误。

我有 3 个实施视图:

  1. UserResetPasswordView
    用户在此处输入电子邮件,请求会发送到他/她的电子邮件
  2. UserResetPasswordRequestSentView
    这里显示电子邮件已发送的消息
  3. 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,
            },
        )

这是用户可以设置新密码的形式(

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>&nbsp;&nbspلطفا صبر کنید';
                $('#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 %}

这里用户应该打开通过电子邮件发送的链接,但每次我尝试将用户重定向到

UserResetPasswordConfirm
时,django都会向我显示此错误:

如果您帮助我,我将非常感激。

django django-views django-templates django-urls django-url-reverse
1个回答
0
投票

使用 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">
    
© www.soinside.com 2019 - 2024. All rights reserved.