2016-04-18 14 views
1

In einer meiner Django-Ansichten, in denen ich Daten posten, ist das Formular ungültig, da es nicht gebunden ist, obwohl das Formular definitiv mit Daten gebunden ist. Ich bin mir nicht ganz sicher, warum das passiert. Die Anwendung, an der ich arbeite, verwendet Angular für das Frontend, also benutze ich in meinem HTML nicht die Formklasse von Django, aber das sollte nicht richtig sein, weil Djangos Formularklasse nur HTML-Widgets erzeugt?Formular nicht bindend in Django

Login Form

login.html

<div class="account-login" id="login-view"> 
    <div class="card card-half"> 
    <h2 class="text-center">Welcome back!</h2> 
    <h4 class="text-center">Sign in to your account.</h4> 

    <div class="alert alert-danger" ng-if="vm.errorMessage"> 
     {{ vm.errorMessage }} 
    </div> 

    <form class="form-horizontal" name="form" ng-submit="vm.login(vm.auth)"> 
     {% csrf_token %} 
     <div class="form-group"> 
     <label for="email" class="col-sm-3 control-label">Email</label> 

     <div class="col-sm-9 col-md-7"> 
      <input type="email" id="email" 
       class="form-control" 
       placeholder="[email protected]" 
       ng-model="vm.auth.email" 
       required 
       hl-focus> 
     </div> 
     </div> 

     <div class="form-group"> 
     <label for="password" class="col-sm-3 control-label">Password</label> 

     <div class="col-sm-9 col-md-7"> 
      <input type="password" id="password" name="password" 
       class="form-control" 
       placeholder="******" 
       ng-model="vm.auth.password" 
       required minlength="6"> 

      <div class="has-warning" ng-if="form.password.$dirty"> 
      <div class="help-block" ng-messages="form.password.$error"> 
       <div ng-message="minlength">Please enter at least six characters. 
       </div> 
      </div> 
      </div> 

     </div> 
     </div> 

     <div class="form-group"> 
     <div class="col-sm-3"></div> 
     <div class="col-sm-9 col-md-7"> 
      <button type="submit" class="btn btn-block btn-secondary" 
       ng-disabled="!form.$valid || vm.submitBusy"> 
      Sign in 
      <span ng-if="vm.submitBusy"><i class="fa fa-circle-o-notch fa-spin"></i></span> 
      </button> 
     </div> 
     </div> 

    </form> 

    </div> 
</div> 

<div class="col-sm-6 col-sm-offset-3"> 
    <p>Forgot your password? Reset it 
     <a ui-sref="auth.reset">here</a>.</p> 
    <p>Trying to create a team? 
     <a ui-sref="auth.join.personal">Sign up</a> to get started.</p> 
</div> 

Form

class LoginForm(forms.Form): 
    email = forms.EmailField(max_length=100) 
    password = forms.CharField(max_length=20) 
    token = forms.CharField(max_length=20) 

    def __init__(self, request=None, *args, **kwargs): 
     self.cached_user = None 
     self.request = request 
     kwargs.setdefault('label_suffix', '') 
     super(LoginForm, self).__init__(*args, **kwargs) 

    def clean(self): 
     cleaned_data = self.cleaned_data 

     if len(self._errors) > 0: 
      return cleaned_data 
     else: 
      email = cleaned_data.get('email') 
      password = cleaned_data.get('password') 

      if email is None or password is None: 
       messages.error(self.request, 'Please enter an email and password.') 
       return forms.ValidationError("Error") 
      else: 
       self.cached_user = authenticate(username=email, password=password) 

       if self.cached_user is None: 
        self._errors["password"] = self.error_class(["Password incorrect. Passwords are case sensitive."]) 
       elif not self.cached_user.is_active: 
        messages.error(self.request, 
            'This account is inactive. Please check your inbox for our confirmation email, and ' 
            'click the link within to activate your account.') 
        raise forms.ValidationError("Error") 

     if not cleaned_data.get('remember_me'): 
      self.request.session.set_expiry(0) 

     return cleaned_data 

    def get_user(self): 
     return self.cached_user 

Ansicht

def login(request): 
    # """ -Log in the user if credentials are valid """ 
    if request.method == "POST": 
     form = LoginForm(request.POST) 

     if form.is_valid(): 
      cleaned_data = form.clean() 

      account = Account.objects.get(email=cleaned_data['email'], password=cleaned_data['password']) 

      if cleaned_data['token']: 

       token = cleaned_data['token'] 
       invite = OrgInvite.objects.get(token=token) 
       org = Org.objects.get(id=invite.org_id) 
       if not invite: 
        raise Exception("Invitation token is invalid.") 
       if invite.used == True: 
        raise Exception("Invitation token has already been used.") 

       org_member = OrgMember.objects.get(account_id=account.id) 
       if org_member: 
        raise Exception("Account is already in team.") 
       else: 
        org.add_members(account.id, False, invite.is_admin) 
        invite.used = False 

        # add_to_welcome(org_id=org.id, account_id=account.id, inviter_id=invite.token) 

      else: 
       pass 

     context = { 
      'message': 'ok', 
      'next': '/app/' 
     } 

     return composeJsonResponse(200, "", context) 

enter image description here

+1

'form.is_valid()' wird 'form.clean()' aufrufen, also sollten Sie es nicht explizit aufrufen. Um Formulardaten nach dem Bereinigen zu erhalten, müssen Sie 'cleaned_data = form.cleaned_data' eingeben. –

+0

Was lässt Sie glauben, dass das Formular nicht gebunden ist oder dass deshalb die Validierung fehlschlägt? –

+0

Beim Debuggen und Festlegen eines Haltepunkts in meiner Sicht wird die Eigenschaft für gebundene Formulare als falsch angezeigt. Ich habe es in ein Bild aufgenommen. Es ist ein winziger Schlitzer am Ende, so dass es ein wenig schwer zu sehen ist. – JBT

Antwort

3

Dies ist ein häufiger Fehler: Sie haben die Signatur der Initialisierungsfunktion der Formularklasse geändert, sodass der erste Parameter die Anforderung ist. Also, wenn Sie LoginForm(request.POST) tun, geht die POST-Daten an die request Argument, nicht die data.

Sie könnte dieses Problem beheben, indem sichergestellt wird, dass Sie immer die Anfrage noch passieren - LoginForm(request, request.POST) - aber eine viel bessere Möglichkeit ist die Signatur nicht zu ändern, und die Anforderung als eine kwarg geben und aus dem **kwargs dict bekommen.

+0

Ahh, ich verstehe, das macht Sinn. Ich habe gerade die Parameter der Formularinitialisierungsfunktion geändert und es kommt nun als gebunden voran, Danke Daniel. – JBT

Verwandte Themen