Django FormView 是有效的,但我需要 add_error 和 return 相同的视图
Django FormView is valid but I need to add_error and return same view
这是我编写的自定义登录视图,因为我需要使用用户的电子邮件而不是用户名登录。
class LoginUser(FormView):
"""
Login with email
"""
template_name = "profiles/login.html"
form_class = LoginForm
success_url = reverse_lazy("client:profile")
def form_valid(self, form):
user_email = form.cleaned_data['user_email']
password = form.cleaned_data['password']
user_object = User.objects.get(email=user_email)
user = authenticate(username=user_object.username, password=password)
# !!! Problem here when user is None
login(self.request, user)
return super(LoginUser, self).form_valid(form)
当user
为None
时,即authenticate
方法returned None
导致密码错误。我需要添加一个错误和 return 相同的视图,但错误是:"wrong username or password"。我如何使用基于 Class 的视图来实现这一点? (我通常使用基于函数的视图,但这次我决定不这样做)。
编辑
Sayse 对这个问题的回答部分有效,它正确地将验证逻辑移至 clean
方法。但是现在我收到错误
Django-AttributeError 'User' object has no attribute 'backend'
当在用户对象上调用 login
而不先在该用户对象上调用 authenticate
时,会发生该错误。我应该将 login
调用放在 clean
方法中吗?
正如 Shang Wang 在评论中指出的那样,您应该在表单的 clean 方法中执行此类操作,但为此您需要传递请求对象。
窗体视图
def get_form_kwargs(self):
kwargs = super(LoginUser, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
登录表单
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(LoginForm , self).__init__(*args, **kwargs)
现在您将能够在表单的 clean 方法中调用身份验证。
authenticate(username=self.request.user.username, password=password)
以上都是无关紧要的,你只需要将你的逻辑移动到表单的 clean 方法中
def clean(self):
cleaned_data = super(LoginForm , self).clean()
user_email = cleaned_data['user_email']
subject = cleaned_data.get("subject")
user_object = User.objects.get(email=user_email)
user = authenticate(username=user_object.username, password=password)
if user is None:
self.add_error('user_email', 'Invalid Password')
这是我编写的自定义登录视图,因为我需要使用用户的电子邮件而不是用户名登录。
class LoginUser(FormView):
"""
Login with email
"""
template_name = "profiles/login.html"
form_class = LoginForm
success_url = reverse_lazy("client:profile")
def form_valid(self, form):
user_email = form.cleaned_data['user_email']
password = form.cleaned_data['password']
user_object = User.objects.get(email=user_email)
user = authenticate(username=user_object.username, password=password)
# !!! Problem here when user is None
login(self.request, user)
return super(LoginUser, self).form_valid(form)
当user
为None
时,即authenticate
方法returned None
导致密码错误。我需要添加一个错误和 return 相同的视图,但错误是:"wrong username or password"。我如何使用基于 Class 的视图来实现这一点? (我通常使用基于函数的视图,但这次我决定不这样做)。
编辑
Sayse 对这个问题的回答部分有效,它正确地将验证逻辑移至 clean
方法。但是现在我收到错误
Django-AttributeError 'User' object has no attribute 'backend'
当在用户对象上调用 login
而不先在该用户对象上调用 authenticate
时,会发生该错误。我应该将 login
调用放在 clean
方法中吗?
正如 Shang Wang 在评论中指出的那样,您应该在表单的 clean 方法中执行此类操作,但为此您需要传递请求对象。
窗体视图
def get_form_kwargs(self):
kwargs = super(LoginUser, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
登录表单
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(LoginForm , self).__init__(*args, **kwargs)
现在您将能够在表单的 clean 方法中调用身份验证。
authenticate(username=self.request.user.username, password=password)
以上都是无关紧要的,你只需要将你的逻辑移动到表单的 clean 方法中
def clean(self):
cleaned_data = super(LoginForm , self).clean()
user_email = cleaned_data['user_email']
subject = cleaned_data.get("subject")
user_object = User.objects.get(email=user_email)
user = authenticate(username=user_object.username, password=password)
if user is None:
self.add_error('user_email', 'Invalid Password')