繁体   English   中英

Django-从表单的clean方法重定向

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM