ray smith
ray smith

Reputation: 380

Return render_to_response from AJAX call

So I'm using an ajax call to log users in for a site. Specifically, I'm using ajax to display a message in a modal if the login did not work. Now if the login does work, then I redirect the user to his respective homepage using python's render_to_response. Now the user get's logged in however, they are not redirected to their homepage. I'm guessing this is happening because I'm not doing it from within the ajax call. I was wondering if there is anyway around this? Here's the view:

def login(request):
    # After login Create class can be called
    if request.POST.get('class_id'):
        return create_class(request)

    if request.POST.get('email'):
        email = request.POST.get('email')
        password = request.POST.get('password')
        user = auth.authenticate(email=email, password=password)

    elif request.session['_auth_user_id']:
        # Instructors Current class and course will be generated on pageload
        sem = get_semester
        year = datetime.now().year
        return render_to_response('home.html', {'sem':sem, 'year':year,
        'inscourses':instructors_current_courses_classes(request),
        'student_class_status':student_current_class_status(request),
        'courses':allCourses()}, context_instance=RequestContext(request))

    if user is not None:
        auth.login(request, user)
        # Instructors Current class and course will be generated on pageload
        sem = get_semester
        year = datetime.now().year
        return render_to_response('home.html', {'sem':sem, 'year': year,
        'inscourses': instructors_current_courses_classes(request),
        'student_class_status': student_current_class_status(request),
        'courses': allCourses()}, context_instance=RequestContext(request))
    else:
        return HttpResponse(json.dumps(True),content_type = 'application/json')

and here is the ajax call:

<script type = "text/javascript"> 
  function login(){
    $.ajax({
      type : "POST",
      url  : "http://localhost:8000/User/home",
      dataType : "json",
      async : true,
      data : {
        csrfmiddlewaretoken : '{{ csrf_token }}',
        email : $('#emailInput').val(),
        password: $('#passwordInput').val()

      },

      success:function(){
        $('#loginError').css("visibility", "visible");          
      },
      error:function(){
        console.log("failed");
      }

    });

  }   
</script>

Upvotes: 2

Views: 486

Answers (1)

Suor
Suor

Reputation: 3055

When you return something from ajax handler it ends up in success handler:

success: function (data) {
    // data here is a chunk of HTML from render_to_response()
}

It's even worse, since you set dataType: json jQuery will try to decode this HTML as JSON and fail, I don't know what happens then.

You should understand several things:

  • any response to Ajax request is not rendered, but decoded and passed to success handler,
  • you can't redirect from server-side if you are handling Ajax request,
  • if you are passing JSON in one case (user is None) then you should always pass JSON.

So you can solve this in 2 ways. First - don't use Ajax login, use ordinary one, you are redirecting on login anyway, so it doesn't add anything to your website.

If for whatever reason you still want to login with Ajax then use something like that:

if user is not None:
    # ...
    return JsonResponse({'success': True})
else:
    return JsonResponse({'success': False, 'message': '...'})

And that:

  success: function(res) {
      if (res.success) window.location.href = '/home';
      else showError(res.message);
  },
  error: function() {
      showError('Failed to connect to server. Please try later.');
  }

Upvotes: 2

Related Questions