Jquery has a funny way of handling 302 redirects during AJAX calls. These frequently come up when I need to redirect a user to a login page. Here’s how I’m handling it with Django.
The underlying problem we experience with redirects in Jquery is that the redirects are followed. So instead of getting a status code of HTTP/1.1 302 Found, we get HTTP/1.1 200 OK. So one way to get around this is to return a made up status code. This is easily accomplished with a middleware in django.
from django.http import HttpResponseRedirect
class AjaxRedirect(object):
def process_response(self, request, response):
if request.is_ajax():
if type(response) == HttpResponseRedirect:
response.status_code = 278
return response
Make sure to add the new middleware to settings.py.
'apps.main.middleware.AjaxRedirect'
And the final piece of the puzzle is to add a global AJAX complete handler, that checks for the new status code, redirects the page to the Location header in the HTTP response, and replace the next query variable. The last part is important because the login_required decorator automatically sets the next query variable to the HTTP Referrer, which in this case would be the URL of the AJAX call. So we want to replace it with the page we’re currently on.
$(document).ready(function() {
$('body').ajaxComplete(function(e, xhr, settings) {
if (xhr.status == 278) {
window.location.href = xhr.getResponseHeader("Location").replace(/\?.*$/, "?next="+window.location.pathname);
}
});
});
« Setting Up Apache-PHP-Python-MySQL on Mac OS X Snow Leopard 10.6 Django Messaging for AJAX Calls Using Jquery »

It’s not jquery but HTTP client (browser in this particular case) that is required to do transparent redirect according to HTTP specification.
This is generic ajax problem and there is several solutions, including custom headers and different response codes in a body.
Personally I wouldn’t recommend this solution – even it feels pretty simple it’s invasive. It intercepts all ajax redirects – which not may be desired.
Better and more precise results can be obtaining by using writing simple custom decorator to replace @login_required