Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Login with Ajax?

I'm working on a jquery function to post a login-form with ajax. In the ajax success: I want to handle the response differently if it's a successful login or not.

So in Django I wonder if i can build on the existing login-view to add some success/error variable to send back to the jquery function together with the returned page. I mean keep the view as it works by default but also add an extra "status" variable.

A small example of this would be great!

like image 586
user3199840 Avatar asked Nov 14 '14 12:11

user3199840


People also ask

Can you use AJAX with Django?

Using Ajax in Django can be done by directly using an Ajax library like JQuery or others. Let's say you want to use JQuery, then you need to download and serve the library on your server through Apache or others. Then use it in your template, just like you might do while developing any Ajax-based application.

Can I use JQuery with Django?

Inside your settings.py file make sure that django. contrib. staticfiles is under INSTALLED_APPS (it is there by default). And now you can use jQuery throughout your site!


3 Answers

your views.py

def logmein(request):
   username= request.GET.get('username')
   password = request.GET.get('pwd')
   stayloggedin = request.GET.get('stayloggedin')
   if stayloggedin == "true":
       pass
   else:
       request.session.set_expiry(0)
   user = authenticate(username=username, password=password)
   if user is not None:
       if user.is_active:
           login(request, user)
           return HttpResponse('fine')
       else:
           return HttpResponse('inactive')
   else:
       return HttpResponse('bad')

your ajax

function logmein() {
    var username = $.trim($('#username').val());
    var pwd = $.trim($('#pwdlogin').val());
    var stayloggedin = document.getElementById('stayloggedin').checked;
    $.ajax({
        url : "/logmein/",
        type : "get",
        data : {
            username: username,
            pwd : pwd,
            stayloggedin : stayloggedin,
            next : next
        }
    }).done(function(data) {
        if (data == "fine") {
            window.location = window.location;
        } 
    });
}
like image 91
doniyor Avatar answered Oct 05 '22 14:10

doniyor


You need to setup an jquery Ajax call to post to your Login view in django.

In the view you need to do something like this...

import json
from django.http import HttpResponse

def login(request):                                                                                                                         
    if request.method == 'POST':                                                                                                                                                                                                           
        login_form = AuthenticationForm(request, request.POST)
        response_data = {}                                                                              
        if login_form.is_valid():                                                                                                           
            response_data['result'] = 'Success!'
            response_data['message'] = 'You"re logged in' 
        else:
            response_data['result'] = 'failed'
            response_data['message'] = 'You messed up'   

        return HttpResponse(json.dumps(response_data), content_type="application/json")  

I have not tested this, but you're ajax call should look something like this.

<script> 
$.ajax({                                                                                                                           
    type:"POST",                                                                                                                    
    url: 'http://www.yousite.com/yourview/login/',                                                                                                   
    data: $('#login_form').serialize(),                                                                                  
    success: function(response){ 
        // do something with response
        response['result']; // equals 'Success or failed';
        response['message'] // equals 'you"re logged in or You messed up';                                                                                                     
     }                                                                                                                             
});
</script>  
like image 37
Chris Hawkes Avatar answered Oct 05 '22 13:10

Chris Hawkes


This is an old question, but in case anyone else runs into this, here is what I did. Please note:

  • I extended the default Django authentication system to use email address in place of the username. (My code should still work even if you use the default)
  • I also used the Django Rest Framework status code (but again this is optional)
  • You will need to set up the default Django registration templates as done here

In your views.py:

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework import status

# Show the login page
def showLoginPage(request):
    return render(request,'registration/login.html',{})

# Actual login logic using AJAX
def login_request(request):
    
    if request.is_ajax and request.method == "POST":
        context = {}
        email = request.POST['username']
        password = request.POST['password']
        
        account = authenticate(request,username=email, password=password)
        if account is None :
            context['message1'] = 'Invalid Login Details!'
            context['message2'] = 'Kindly Try Again With A Valid Email And Password'
            context['code']=status.HTTP_401_UNAUTHORIZED            
            return JsonResponse(context, status = 200)
        
        elif account is not None and not account.is_active:
            context['message1'] = 'Sorry, your account is in-Active'
            context['message2'] = 'Kindly Check Your Email For Activation Link Or Contact Support'
            context['status'] = 'Error!'  
            context['code']=status.HTTP_401_UNAUTHORIZED           
            return JsonResponse(context, status = 200)
        
        elif account :
              login(request, account)
              context['message'] = 'Successfully authenticated.'
              context['status'] = 'Success!'
              context['code']=status.HTTP_200_OK                                   
              return JsonResponse(context, status = 200) 

        else:           
            context['message'] = 'Invalid credentials'
            context['message2'] = 'Kindly Try Again With A Valid Email And Password'
            context['code']=status.HTTP_401_UNAUTHORIZED           
            return JsonResponse(context, status = 200)

    return JsonResponse({}, status = 200)

urls.py:

# default page = login page
path('', views.showLoginPage, name='login'),
# ajax login
path('post/ajax/loginUser', views.login_request, name='loginUser'),
# home page once logged in
path('home/', views.home, name='home'),

login.html:

<!-- this div displays our response from the ajax post -->
<div id="login_error_div" style="display: none;" class="alert alert-warning alert-dismissible fade show text-center" role="alert">
  <strong><span id="error1"></span></strong>
  <span id="error2"></span>
  <button id="hide_msg" type="button" class="close"  aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

<!-- a hidden url to re-direct to the home page if successful -->
<input type="hidden" id="Urlhome" data-url="{% url 'home' %}" />

<script src="/static/plugins/jquery/jquery.min.js"></script>

<script>
  (function() {
    'use strict';
    window.addEventListener('load', function() {
      // Fetch all the forms we want to apply custom Bootstrap validation styles to
      var forms = document.getElementsByClassName('needs-validation');
      // Loop over them and prevent submission
      var validation = Array.prototype.filter.call(forms, function(form) {
        form.addEventListener('submit', function(event) {
          if (form.checkValidity() === false) {
            event.preventDefault();
            event.stopPropagation();
          }else{
              sign_in_User()
          }                
          form.classList.add('was-validated');
        }, false);
      });
    }, false);
  })();
</script>

<script>
  const togglePassword = document.querySelector('#togglePassword');
  const password = document.querySelector('#id_password');
  togglePassword.addEventListener('click', function (e) {
    // toggle the type attribute
    const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
    password.setAttribute('type', type);
    // toggle the eye slash icon
    this.classList.toggle('fa-lock-open');
  });
</script>    

<script>    
  $("#hide_msg").click(function (){    
    $("#login_error_div").hide()
  });
</script>

<script>
  function sign_in_user() {
    var url = $("#Urlhome").attr("data-url");
    event.preventDefault();
    event.stopPropagation();  
    var username = ($('#id_username')).val();
    var password = ($('#id_password')).val();  
    $.ajax({
      url: "{% url 'loginUser' %}",  
      type: "POST", // or "get"
      headers: {'X-CSRFToken': '{{ csrf_token }}'}, // for csrf token
      data:{
        'username': username, 
        'password':password,
      },
      success: function loginResponse(response) {  
        if(response['code']=== 401){
          $('#login_error_div').show();
          $("#error1").text(response['message1']+' :')
          $("#error2").text(response['message2'])                      
        } else {
          location.href=url;
        }                                     
      }
    });   
  }    
</script>
like image 27
Nkem Avatar answered Oct 05 '22 13:10

Nkem