django - 使用自定义 AuthenticationForm 覆盖 Django LoginView 错误消息
问题描述
我有一个基于类的子类视图LoginView
。
from django.contrib.auth.views import LoginView
class CustomLoginView(LoginView):
def get_success_url(self):
url = self.get_redirect_url()
return url or reverse_lazy('knowledgebase:user_home', kwargs={
'username':self.request.user.username,
})
如果用户的电子邮件尚未激活,我想覆盖错误消息,因为他们必须单击发送到其电子邮件地址的链接。当前的默认消息如下所示:
而不是说:
请输入正确的电子邮件地址和密码。两个地方都要注意大小写。
我想说几句大意:
请确认您的电子邮件,以便您可以登录。
我试过了:
帐户/forms.py
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import gettext as _
class PickyAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
_("Please confirm your email so you can log in."),
code='inactive',
)
帐户/views.py
class CustomLoginView(LoginView): # 1. <--- note: this is a class-based view
form_class = PickyAuthenticationForm # 2. <--- note: define form here?
def get_success_url(self):
url = self.get_redirect_url()
return url or reverse_lazy('knowledgebase:user_home', kwargs={
'username':self.request.user.username,
})
当我尝试使用确实存在但尚未验证其电子邮件地址的用户登录时,结果绝对无效。
解决方案
方法 - 1
Django 使用ModelBackend
默认值AUTHENTICATION_BACKENDS
,它不对非活动用户进行身份验证。
这也在对非活动用户的授权部分中进行了说明,
非活动用户是其
is_active
字段设置为的用户False
。和ModelBackend
身份RemoteUserBackend
验证后端禁止这些用户进行身份验证。如果自定义用户模型没有is_active
字段,则将允许所有用户进行身份验证。
所以,设置AllowAllUsersModelBackend
为你AUTHENTICATION_BACKENDS
的settings.py
# settings.py
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.AllowAllUsersModelBackend']
它对我的 Django 应用程序有多大影响?
它不会影响身份验证以外的任何内容。如果我们查看类的源代码,AllowAllUsersModelBackend
我们可以看到它只是允许非活动用户进行身份验证。
方法 - 2
就个人而言,我不推荐这种方法,因为方法 1是 Django 解决这个问题的方法。
覆盖类的clean(...)
方法PickyAuthenticationForm
并将AllowAllUsersModelBackend
后端称为,
from django.contrib.auth.backends import AllowAllUsersModelBackend
class PickyAuthenticationForm(AuthenticationForm):
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username is not None and password:
backend = AllowAllUsersModelBackend()
self.user_cache = backend.authenticate(self.request, username=username, password=password)
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
"Please confirm your email so you can log in.",
code='inactive',
)
结果截图
推荐阅读
- wpf - MVVM 中的条件逻辑与重复
- javascript - 在 Selenium 测试期间访问 redux 状态
- qt - Qt MQTT 包是否提供了一种编写我自己的代理的简单方法?
- shopizer - 如果可能的话,如何自定义 Shopizer 中的类别和产品字段?
- angular - 如何在不使用本机 API/DOM 方法(而是使用 Angular API)的情况下以编程方式获取 Angular 中的元素引用?
- c# - 动态更改过期身份验证 cookie .net 核心身份
- postgresql - 暂时跳过 RLS 检查
- android - 在 android 版本 10 中使用 camera2 api 捕获时出现图像方向问题
- latex - 制作 PDF 时如何替换 Sphinx 封面
- scala - Play framework 2.5 不会将请求流式传输到响应中