2016-05-17 87 views
0

我有Django的登录表单,在那里我需要做一些额外的检查我的清洁方法重定向: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 

它可以正常工作,但是当凭据是正确的,但用户(is_active = False)我想将用户重定向到另一个视图并添加一些Flash消息(也许使用django.contrib.messages)。

是否有可能做这样的重定向?

谢谢!

+1

它是负责返回HTTP响应(包括重定向)的* view *。表单负责处理输入数据。他们不会返回响应,因此您无法从表单内部重定向。 – Alasdair

+0

如何查看可能知道是否应该重定向或什么?我应该从表格中返回什么? – dease

回答

2

你可以只添加一个布尔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}) 
0

当你在你的形式提高验证错误,你可以指定一个特定的错误代码。

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 
0

所以我会冒险猜测你还想在重定向用户之前在FIRST登录用户。

如果以上情况属实,请先完成表单的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')