客户需要管理员具有将用户添加到公司(具有随机一次密码)的能力,在该公司中,用户必须在访问任何内容之前更改其密码。我正在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 /
答案 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
的用户的用户名传递给用户,并有一个表单等待用户那里输入新密码一个并确认新密码。这是您要做的最简单的方法,但是您将不得不再次确认用户当前的密码是正确的。
对不起,我的第一个答案很困惑,我不是第一次才读到这个问题,希望这更有意义:)