【问题标题】:Can't route reset email link to password reset view无法将重置电子邮件链接路由到密码重置视图
【发布时间】:2016-10-29 17:33:54
【问题描述】:

我正在 django 中通过电子邮件开发密码重置。我已经正确发送了包含密码重置链接的电子邮件,问题是当用户单击电子邮件中的密码重置链接时,被重定向到“将重置链接发送到邮件”而不是“输入新密码链接” .

网址如下:

 url(r'^login/$', views.Login, name='login'),
 url(r'^register/$', views.Register.as_view(),  name='register'),
 url(r'^reset_password', views.ResetPasswordRequestView.as_view(), name="password_reset"),
 url(r'^reset_password_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'),

用户用来输入他的电子邮件的模板是这个模板(为了简洁起见,在模板化和条带化的基础中使用):

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit"/>
</form>

处理发送密码重置链接的视图:

class ResetPasswordRequestView(FormView):
template_name = 'authentication/password_reset.html'
success_url = 'login'
form_class = PasswordResetRequestForm

def get(self, request, *args, **kwargs):
    form = PasswordResetRequestForm()
    return render(request, 'authentication/password_reset.html', {'form': form})

def post(self, request, *args, **kwargs):
    '''
    A normal post request which takes input from field "email" (in ResetPasswordRequestForm).
    '''
    form = self.form_class(request.POST)
    form_email = ''
    if form.is_valid():
        form_email = form.cleaned_data["email"]
    if self.validate_email_address(form_email):  # uses the method written above
        '''
        Verifies that the submited email is valid and gets its asociated user. If it is registered an
        email will be sent to that address with the reset link
        '''
        user = User.objects.get(email=form_email)
        if user is not None:
            email_template_data = {
                'email': user.email,
                'domain': request.META['HTTP_HOST'],
                'site_name': 'Collector',
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'user': user,
                'token': default_token_generator.make_token(user),
                'protocol': 'http',
            }
            email_template_name = 'authentication/password_reset_email.html'
            subject = 'Password reset on Collector'
            email = loader.render_to_string(email_template_name, email_template_data)

            send_mail(subject, email, DEFAULT_FROM_EMAIL, [user.email], fail_silently=False)
            result = self.form_valid(form)
            messages.success(request,
                         'An email has been sent to ' + form_email + ". Please check its inbox to continue reseting password.")
            return result
        else:
            result = self.form_invalid(form)
            messages.error(request, 'No user is associated with this email address')
            return result

    messages.error(request, 'Invalid Input')
    return self.form_invalid(form)

处理nre密码输入的视图如下:

class PasswordResetConfirmView(FormView):
"""
    View that checks the hash in a password reset link and presents a
    form for entering a new password.
"""
template_name = "authentication/password_reset_enter_new.html"
success_url = 'login'
form_class = SetPasswordForm

def get(self, request, uidb64=None, token=None, *arg, **kwargs):
    form = SetPasswordForm()
    return render(request, "authentication/password_reset_enter_new.html", {'form': form})

def post(self, request, uidb64=None, token=None, *arg, **kwargs):

    UserModel = User
    form = self.form_class(request.POST)
    assert uidb64 is not None and token is not None  # checked by URLconf
    try:
        uid = urlsafe_base64_decode(uidb64)
        user = UserModel._default_manager.get(pk=uid)
    except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
        user = None

    if user is not None and default_token_generator.check_token(user, token):
        if form.is_valid():
            new_password = form.cleaned_data['new_password']
            user.set_password(new_password)
            user.save()
            messages.success(request, 'Password has been reset.')
            return self.form_valid(form)
        else:
            messages.error(request, 'Password reset has not been unsuccessful.')
            return self.form_invalid(form)
    else:
        messages.error(request, 'The reset password link is no longer valid.')
        return self.form_invalid(form)

我的问题是发送给用户的 url 没有路由到 PasswordResetConfirmView,这个 url 如下:

127.0.0.1:8000/authentication/reset_password_confirm/MQ-4gk-262cd9422172a2e21be1/

非常感谢任何帮助或输入!

【问题讨论】:

    标签: python django model-view-controller django-templates django-views


    【解决方案1】:

    您需要终止您的 reset_password URL:

    url(r'^reset_password/$', ...)
    

    否则它将匹配 开始 与该字符串的所有内容。

    另请注意,Django 已经内置了大部分此类功能。

    【讨论】:

      猜你喜欢
      • 2021-02-05
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 2016-04-04
      • 2016-07-14
      • 2019-05-25
      相关资源
      最近更新 更多