2016-04-19 14 views
1

Ich versuche, Eingabedaten aus einem Formular, das ich in meiner Django/Angular-Anwendung habe. Das Problem ist jedoch, dass, wenn ich das Formular ausfülle und es abschicke, das Formular nicht sagt, dass alle meine Felder benötigt werden. Ich bin mir nicht sicher, ob dies ein Django-Problem, ein menschlicher Fehler oder wegen Angular ist. Der Grund, warum ich denke, dass es angular ist, liegt daran, dass mein csrf_token auch auf die Seite rendert. gründlich verwirrt.Keine Anfrage POST-Daten vom Formular in Django anzeigen

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': form.errors, 
     'next': '/app/' 
    } 

    return composeJsonResponse(200, "", context) 

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, *args, **kwargs): 
    self.cached_user = None 
    self.request = kwargs 
    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 

enter image description here

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> 

Angular

(function() { 
    'use strict'; 

Login.$inject = ["$log", "$anchorScroll", "$stateParams", "AccountRepo", "CommonService", "CommonEvents"]; 
angular 
    .module('app.guest') 
    .controller('Login', Login); 

    /** @ngInject */ 
    function Login($log, $anchorScroll, $stateParams, 
        AccountRepo, CommonService, CommonEvents) { 
     var vm = this; 

     var next = null; 
     var defaultAuth = { 
      email: '', 
      password: '' 
     }; 

     vm.errorMessage = null; 
     vm.submitBusy = false; 
     vm.auth = angular.copy(defaultAuth); 
     vm.login = login; 

     init(); 

     function init() { 
      CommonService.broadcast(CommonEvents.viewReady); 
      next = $stateParams.next; 
     } 

     function login(model) { 
      vm.submitBusy = true; 
      vm.errorMessage = null; 
      AccountRepo.login(model).then(
       function (data) { 
        // CommonService.hardRedirect(next || '/app'); 
        console.log(data) 
       }, 
       function (data) { 
        vm.submitBusy = false; 
        vm.errorMessage = data; 
        $anchorScroll('login-view'); 
       }); 
     } 
    } 

})(); 

(function() { 
    'use strict'; 

AccountRepo.$inject = ["$q", "$log", "AbstractRepo"]; 
angular 
    .module('app.repo') 
    .factory('AccountRepo', AccountRepo); 

function AccountRepo($q, $log, AbstractRepo) { 

     return { 
      accept: accept, 
      invite: invite, 
      join: join, 
      login: login, 
      save: save 
     }; 

     /** 
     * Create a new account with a new team. 
     * @param model: 
     * @returns {*} 
     */ 
     function join(model) { 
      return AbstractRepo.post('accounts/signup', model, false) 
       .then(genericSuccess, genericError); 
     } 

     /** 
     * Authenticate an account. 
     * @param model: 
     * @returns {*} 
     */ 
     function login(model) { 
      return AbstractRepo.post('accounts/login/', model, false) 
       .then(genericSuccess, genericError); 
     } 

angular 
     .module('app.repo') 
     .factory('AbstractRepo', AbstractRepo); 

/** ngInject */ 
function AbstractRepo($log, $http, $q, Config) { 

    return { 
     get: get, 
     post: post, 
     put: put, 
     genericSuccess: genericSuccess, 
     genericError: genericError 
    }; 

    function get(uri, data, isApi) { 
     return httpRequest('GET', uri, data, isApi); 
    } 

    function post(uri, data, isApi) { 
     return httpRequest('POST', uri, data, isApi); 
    } 

    function put(uri, data, isApi) { 
     return httpRequest('PUT', uri, data, isApi); 
    } 

    function httpRequest(method, uri, data, isApi) { 
     isApi = angular.isDefined(isApi) ? isApi : true; 

     var deferred = $q.defer(); 
     var promise = $http({ 
      method: method, 
      url: (isApi ? Config.api_path : '/') + uri, 
      data: data || {}, 
      timeout: deferred.promise 
     }).catch(function (response) { 
      $log.error(response); 
      return $q.reject(response); 
     }).finally(function() { 
      promise.abort = angular.noop; 
      deferred = null; 
      promise = null; 
     }); 
     // Abort the underlying request. 
     promise.abort = function() { 
      deferred.resolve(); 
     }; 
     return promise; 
    } 

    function genericSuccess(response) { 
     return response.data; 
    } 

    function genericError(response) { 
     var reason = "Oops, something went wrong. That's our bad."; 
     if (response.status < 500 && response.data.message) { 
      reason = response.data.message; 
     } 
     return $q.reject(reason); 
    } 

} 

Ablaufverfolgung, nachdem request.body in LoginForm gesetzt wurde. Der Fehler tritt auf, wenn meine Ansicht die form.is_valid() -Methode trifft.

ERROR 2016-04-19 10:57:38,949 base.py handle_uncaught_exception 284 Internal Server Error: /accounts/login/ 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "/Users/timothybaney/Django_Projects/human_link/backend/account/views.py", line 70, in login 
    if form.is_valid(): 
    File "/usr/local/lib/python2.7/site-packages/django/forms/forms.py", line 161, in is_valid 
    return self.is_bound and not self.errors 
    File "/usr/local/lib/python2.7/site-packages/django/forms/forms.py", line 153, in errors 
    self.full_clean() 
    File "/usr/local/lib/python2.7/site-packages/django/forms/forms.py", line 362, in full_clean 
    self._clean_fields() 
    File "/usr/local/lib/python2.7/site-packages/django/forms/forms.py", line 374, in _clean_fields 
    value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) 
    File "/usr/local/lib/python2.7/site-packages/django/forms/widgets.py", line 231, in value_from_datadict 
    return data.get(name) 
AttributeError: 'str' object has no attribute 'get' 
+0

Ist Ihr AngularJS diese Linie schlagen? Funktion (Daten) { // CommonService.hardRedirect (next || '/ app'); console.log (Daten) }, welches ist der Wert von Daten? – lapinkoira

+0

Ja, ich habe "CommonService.hardRedirect (next || '/ app')" auskommentiert, um herauszufinden, wo das Problem lag, aber wenn es nicht auskommentiert ist, wird es den hardRedirect tun. – JBT

+0

Was sind Insiderdaten? – lapinkoira

Antwort

0

Ich schätze die Hilfe alle! Ich habe herausgefunden, was das Problem war. Ich fühle mich komisch, meine eigenen Fragen zu beantworten, aber nur für den Fall, dass andere Leute das gleiche Problem haben, werde ich Links zu anderen Stack-Überlauf-Artikeln hinzufügen, die mir geholfen haben, es herauszufinden. Grundsätzlich, da Angular AJAX-Aufrufe verwendet, konnte ich request.POST nicht verwenden. Ich musste request.body verwenden. Da eine AJAX-Post nur json ist, musste ich request.body in ein Query Dictionary umwandeln, das in meinem Login-Formular verwendet wird.

# Converts AJAX JSON into query dictionary for the view to process. 
def requestPost(request): 
    querystring = urllib.urlencode(ast.literal_eval(request.body)) 
    postdata = QueryDict(query_string=querystring) 

    return postdata 

def login(request): 
    if request.is_ajax(): 
     if request.method == "POST": 
      form = LoginForm(requestPost(request)) 

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

       if len(form.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(form.request, 'Please enter an email and password.') 
         return form.ValidationError("Error") 
        else: 
         form.cached_user = authenticate(username=email, password=password) 

         if not form.cached_user: 
          x = True 
         else: 
          x = False 

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

       return cleaned_data 

       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': form.errors, 
       'next': '/app/' 
      } 

      return composeJsonResponse(200, "", context) 

Verwandte Stapelüberlauf Fragen.

Where's my JSON data in my incoming Django request?

Django: Can I create a QueryDict from a dictionary?