[英]Django - redirect from form's clean method
我在django中有一个登录表单,在这里我需要在我的干净方法中做一些额外的检查:
class LoginForm(BootstrapFormMixin, forms.Form):
email = forms.EmailField(required=True, max_length=30)
password = forms.CharField(required=True, widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = self.__class__.__name__.lower()
self.helper.form_action = ''
self.helper.layout = Layout(
Field('email'),
Field('password'),
Div(
Submit('submit', _('Login'),
css_class="btn btn-block btn-success"),
css_class=''
)
)
def clean(self):
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
user = authenticate(email=email, password=password)
if user:
company = user.company
if not company.is_active:
# here I want to make a redirect; if is it possible to add a flash message it would be perfect!
raise forms.ValidationError(_('Account activation is not finished yet'))
else:
raise forms.ValidationError(_('Invalid credentials'))
return self.cleaned_data
它正常工作,但是当凭据正确时,但是与用户相关的名为company的对象未处于活动状态(is_active = False),我想将用户重定向到另一个视图并添加一些闪存消息(也许使用django.contrib.messages
)。
是否可以进行这种重定向?
谢谢!
您可以只向表单添加一个布尔redirect
属性,以知道何时进行重定向:
class LoginForm(BootstrapFormMixin, forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.redirect = false
. . .
def clean(self):
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
user = authenticate(email=email, password=password)
if user:
company = user.company
if not company.is_active:
self.redirect = True
raise forms.ValidationError()
else:
raise forms.ValidationError(_('Invalid credentials'))
return self.cleaned_data
from django.contrib import messages
from django.shortcuts import redirect
def your_view(request):
form = LoginForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
# whatever
else:
if form.redirect:
messages.add_message(request, messages.ERROR,
_('Account activation is not finished yet'))
return redirect('wherever')
return render(request, 'your-template.html', {'form': form})
当您在表单中引发验证错误时,可以指定特定的错误代码。
def clean(self):
...
if not company.is_active:
# here I want to make a redirect; if is it possible to add a flash message it would be perfect!
raise forms.ValidationError(_('Account activation is not finished yet'), code='inactive')
然后,您可以在视图中检查错误代码,并在适当时重定向。 您可以使用form.errors.as_data()
检查错误代码。 由于您在clean
方法中引发了ValidationError
,因此该错误不属于特定字段,因此您可以使用__all__
键来访问它。
if form.is_valid():
# login user then redirect
else:
for error in form.errors.as_data()['__all__']:
if error.code == 'inactive':
messages.warning(request, 'Account is inactive')
return redirect('/other-url/')
# handle other errors as normal
因此,我冒着一个猜测,即您仍然要在重定向用户之前先将用户登录。
如果以上是正确的,请首先完成表单的PRIMARY功能。
重定向可以在“视图”中运行,在该视图中需要先运行用户登录功能,然后才能重定向用户。 在此之前,无需运行其他验证。
这是我为视图编写代码片段的方式-仅用于显示与重定向相关的步骤(而不是整个视图)。 假设“ home:index”将用户登录后路由到正常的重定向页面,而“ company:add_company_info”将用户带消息路由到异常页面。
if form.is_valid():
user = form.login(request) # assume this form function calls django authenticate and will return the user if successful
if user:
login(request, user)
if user.company.is_active: # this is assuming the user.company relationship exists
return redirect('home:index')
else:
messages.add_message(request, messages.INFO, "Please fill in your company information")
return redirect('company:add_company_info')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.