title: Django login_required decorator with AJAX
body: <p>I found <a href="https://stackoverflow.com/questions/312925/django-authentication-and-ajax-urls-that-require-login">one</a> question similar to this, but not sure the solution is the best (it doesn't seem very DRY) and it is quite old so I hope its ok that I ask another one.</p>
  
  <p>I have a django project with various pages that require you to be logged in to view them. It is quite simple to get django to redirect to a login page if you are not logged in but what I would like to do is to bring up a modal login with javascript. Obviously I could go through each link and determine manually whether it required login and assign a class to those links or something but I think there must be a better way. </p>
  
  <p>I was thinking possibly along the lines of replacing the built in url template tag with my own that checks if the view is login required (not sure if this is possible) and then if it is, replaces the url with something that can be recognised by javascript to assign a click handler to bring up the modal. Ideal solutions would somehow allow for people without javascript to still be redirected to the login page.</p>
  
  <p>Am I asking too much?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Ok, have come up with some basic code so I'm hoping that might encourage someone to point out where I am going wrong/right. I think that you probably can't check whether a view is login_required with a template tag and so perhaps a decorator for the views is the best option.</p>
  
  <pre><code>#decorators.py
  def AJAX_login_required(view_func):
      @wraps(view_func)
      def wrapper(request, *args, **kwargs):
          if request.is_ajax():
              if not request.user.is_authenticated():
                  return HttpResponse(json.dumps({'login_required': True}), mimetype='application/json')
          else:
              if request.user.is_authenticated():
                  return view_func(request, *args, **kwargs)
              else:
                  path = request.get_full_path()
                  login_url = reverse('login')
                  return redirect_to_login(path, login_url, 'next')
      return wrapper
  
  #views.py
  @AJAX_login_required
  def view_which_requires_login(request):
      //etc.
  
  def view_that_does_not(request):
      //etc.
  
  #javascript
  $('a').click(function(e) {
      var link = $(this).attr('href');
      $.ajax({
          type:"POST",
          url:link,
          data:'',
          success: function(response){
              if (response.login_required) {
                  //open modal login
                  return;
              }
              else {
                  document.location.href = link;
              }
          },
          error: function(){
              document.location.href = link;
          }
     });
  });
  </code></pre>
  
  <p>I think this should result in what I want but it does require that every page that doesn't require login be effectively sent twice. Once to the ajax query and then again when the page is redirected. Is there a better way?</p>