Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Ajax login form

I am trying to submit a login form using ajax. I am confused as to how I am supposed to handle the exceptions/successful responses. I am getting a 200 OK from the server and the form returns error's either by the password/username field. How can I get a error message for to display or redirect the user to the appropriate page depending on the server response?

JQUERY:

56 $(window).load(function(){                                                                                                                  
57 $('#login_form').submit(function(e){                                                                                                        
58             e.preventDefault();                                                                                                             
59     var request_url = document.getElementById('next').value                                                                             
60          $.ajax({                                                                                                                           
61             type:"POST",                                                                                                                    
62             url: $(this).attr('action'),                                                                                                    
63             data: $('#login_form').serialize(),                                                                                             
64             success: function(response){ $('#msg').text(response);                                                                          
65             console.log(response);                                                                                                          
66             },                                                                                                                              
67             error: function(xhr, ajaxOptions, thrownError){ alert( $('#login_error').text('Username already taken. Please select another one.')}, 
68           });                                                                                                                               
69     });                                                                                                                                     
70 }); 

VIEW: UPDATED

51 def login(request):                                                                                                                         
52     if request.method == 'POST':                                                                                                            
53         request.session.set_test_cookie()                                                                                                   
54         login_form = AuthenticationForm(request, request.POST)                                                                              
55         if login_form.is_valid():                                                                                                           
56             if request.is_ajax:                                                                                                             
57                 user = django_login(request, login_form.get_user())                                                                         
58                 if user is not None:                                                                                                        
59                     return HttpResponseRedirect(request.REQUEST.get('next', '/'))
           **else:**                                                                                                                               
61                **return HttpResponseForbidden() # catch invalid ajax and all non ajax**                                        
60     else:                                                                                                                                   
61         login_form = AuthenticationForm(request)                                                                                            
62                                                                                                                                             
63     c = Context({                                                                                                                           
64         'next': request.REQUEST.get('next'),                                                                                                
65         'login_form': login_form,                                                                                                           
66         'request':request,                                                                                                                  
67     })                                                                                                                                      
68     return render_to_response('login.html', c, context_instance=RequestContext(request))    

FORM:

7   <tt id="login_error"></tt>                                                                                                                            
8   <form id="login_form" action="" method="post">                                                                                            
9                                                                                                                                             
10     {{ login_form }}                                                                                                                        
11     <input type="submit" value="login"/>                                                                                                    
12     <input type="hidden" id="request_path" name="next" value="/"/>                                                                          
13   </form>                                                                                                                                   
14 <p>{{ request.get_full_path }}</p>                                                                                                          
15 <tt id='msg'></tt>         
like image 745
user1462141 Avatar asked Dec 09 '12 02:12

user1462141


1 Answers

Although it's certainly better practice to do this with a json, you can get away without, assuming you're not really passing much info back from the server. On the django side swap out the HttpResponseRedirect for an HttpResponse using the redirect URL as your message. Also add an HttpResponseForbidden for the case that ajax login fails.

def login(request):                                                                                                                         
    if request.method == 'POST':                                                                                                            
        request.session.set_test_cookie()                                                                                                   
        login_form = AuthenticationForm(request, request.POST)                                                                              
        if login_form.is_valid():                                                                                                           
            if request.is_ajax:                                                                                                             
                user = django_login(request, login_form.get_user())                                                                         
                if user is not None:                                                                                                        
                    return HttpResponse(request.REQUEST.get('next', '/'))   
        return HttpResponseForbidden() # catch invalid ajax and all non ajax                                                        
    else:                                                                                                                                   
        login_form = AuthenticationForm()                                                                                                                                        
    c = Context({                                                                                                                           
        'next': request.REQUEST.get('next'),                                                                                                
        'login_form': login_form,                                                                                                                         
        'request':request,                                                                                                                  
    })                                                                                                                                      
    return render_to_response('login.html', c, context_instance=RequestContext(request))

Then on the javascript side, check the status code of the response. If it's 200, then that's your HttpResponse - you want to redirect to the url in the response message. If it's a 403, then that's your HttpResponseForbidden - login has failed. You can get away with a standard 'login failed' error message.

$.ajax({                                                                                                                           
    type:"POST",                                                                                                                    
    url: $(this).attr('action'),                                                                                                    
    data: $('#login_form').serialize(),  
    // the success function is called in the case of an http 200 response                                                                                  
    success: function(response){ 
        // redirect to the required url
        window.location = response;                                                                                                     
     },                                                                                                                              
    error: function(xhr, ajaxOptions, thrownError){
        alert('login failed - please try again'); 
    }, 
}); 

I'm afraid I haven't tested this, but it should give you an idea.

For more info look at the docs for django's HttpResponse objects. Then check out the jquery ajax docs.

like image 78
Aidan Ewen Avatar answered Sep 28 '22 07:09

Aidan Ewen