首次登录时强制更改密码(Django)

时间:2019-07-02 14:48:45

标签: django authentication

客户需要管理员具有将用户添加到公司(具有随机一次密码)的能力,在该公司中,用户必须在访问任何内容之前更改其密码。我正在Django 2.2中开发应用程序

我创建了一个自定义用户,用电子邮件地址替换了用户名,并向该用户添加了一个change_password bool标志。我的change_password表单/功能正常运行,但重定向不起作用。

urls.py

path('change-password/', views.change_password, name='change-password'),

views.py

class Login(LoginView):
    def form_valid(self, form):
        # form is valid (= correct password), now check if user requires to set own password
        if form.get_user().change_password:
            return HttpResponseRedirect(reverse('change-password'))
        else:
            auth_login(self.request, form.get_user())
            return HttpResponseRedirect(self.get_success_url())


def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(data=request.POST, user=request.user)

        if form.is_valid():
            form.save()
            request.user.change_password = False
            request.user.save()
            update_session_auth_hash(request, request.user)
            return redirect(reverse('user_view'))
        else:
            return redirect(reverse('change-password'))
    else:
        form = PasswordChangeForm(user=request.user)

        args = {'form': form}
        return render(request, 'users/change_password.html', args)

如果change_password标志为True,则预期的行为是重定向到更改密码,但是,当应用程序确实重定向到更改密码时,在提交时会引发以下错误:

NotImplementedError:Django不为AnonymousUser提供数据库表示。

如果将装饰器@login_required添加到我的change_password函数中,此错误就消失了,但是,我使用URL重定向回登录页面:users / login /?next = / users / change-password /

1 个答案:

答案 0 :(得分:1)

问题在于,在form_valid方法中,您正在调用form.get_user()来对用户进行身份验证/获取并检查change_password,但它没有使用户登录,这意味着发出请求的用户对系统仍然是匿名的。因此,当用户被重定向时,他们没有经过身份验证,这意味着request.user对象的类型为AnonymousUser,该类型不存在于数据库中,因此 Django不为以下对象提供数据库表示形式: AnonymousUser 错误。

当您使用@login_required装饰器时,用户将被重定向到登录页面,因为它不是已登录用户,并且装饰器要求用户登录才能看到其正在装饰的视图。

您看到的users/login/?next=/users/change-password/网址基本上就是login_required装饰器的工作方式,它在做两件事: 1.将匿名用户重定向到登录页面(URL的users/login部分) 2.成功登录后,将他们从(?next=/users/change-password/)的位置重定向回

我的建议是,您将尝试登录但必须将其密码更改为change_password的用户的用户名传递给用户,并有一个表单等待用户那里输入新密码一个并确认新密码。这是您要做的最简单的方法,但是您将不得不再次确认用户当前的密码是正确的。

对不起,我的第一个答案很困惑,我不是第一次才读到这个问题,希望这更有意义:)