2016-05-17 5 views
0

ich ein Login-Formular in django habe, wo ich einige zusätzliche Kontrollen in meiner sauberen Methode zu tun:Django - von der Form sauberen Methode umleiten

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 

Es funktioniert, aber wenn Anmeldeinformationen korrekt sind, aber der Benutzer verwandtes Objekt namens Firma ist nicht aktiv (is_active = False) Ich möchte den Benutzer in eine andere Ansicht umleiten und eine Flash-Nachricht hinzufügen (möglicherweise unter).

Ist eine solche Umleitung möglich?

Vielen Dank!

+1

Es ist die * Ansicht *, die für die Rückgabe einer HTTP-Antwort (einschließlich Weiterleitungen) verantwortlich ist. Formulare sind für die Verarbeitung der Eingabedaten zuständig. Sie geben keine Antworten zurück, sodass Sie nicht von innerhalb des Formulars umleiten können. – Alasdair

+0

Wie kann Ansicht wissen, ob es Redirect oder etwas geben sollte? Was soll ich vom Formular zurückgeben? – dease

Antwort

2

könnten Sie fügen Sie einfach einen boolean redirect Attribut auf das Formular zu wissen, wann die Umleitung zu tun:

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

Sie einen bestimmten Fehlercode angeben können, wenn Sie den Validierungsfehler in Ihrem Formular zu erhöhen.

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') 

In der Ansicht können Sie dann die Fehlercodes überprüfen und gegebenenfalls umleiten. Sie können die Fehlercodes mit form.errors.as_data() überprüfen. Da Sie die ValidationError in der clean-Methode auslösen, gehört der Fehler nicht zu einem bestimmten Feld, so dass Sie mit dem Schlüssel darauf zugreifen können.

0

Also werde ich eine Vermutung riskieren, dass Sie immer noch den Benutzer in FIRST anmelden möchten, bevor Sie den Benutzer umleiten.

Wenn das Obige wahr ist, führen Sie zuerst die PRIMARY-Funktionalität des Formulars aus.

Die Umleitung kann in "Ansichten" ausgeführt werden, in denen die Benutzeranmeldefunktion zuerst ausgeführt werden muss, BEVOR Sie den Benutzer umleiten können. Vor diesem Zeitpunkt ist keine zusätzliche Überprüfung erforderlich.

Hier ist, wie ich das Snippet für die Ansicht schreiben würde - nur um die Redirect verbundenen Schritte (nicht die gesamte Ansicht) zu zeigen. Angenommen, 'home: index' leitet den Benutzer nach der Anmeldung an die normale Weiterleitungsseite weiter und 'company: add_company_info' leitet den Benutzer an die fehlerhafte Seite mit der Nachricht weiter.

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')