Prosthetic Conscience

Jason McBrayer's weblog; occasional personal notes and commentary

Sun, 21 Aug 2005

Redirects in Django

While working on the authentication bits for a feed-reader application I’m writing (more on that later), I noticed that polipo was cacheing my redirects. This is bad, because I’m using a decorator on most of my views that checks if a user is logged in, and, if not, redirects them to the login page. It looks like this, and is basically copied from the django admin code:

def login_required(view_func):
    “””
    Decorator for views that checks that the user is logged in, redirecting
    to the log-in page if necessary.
    “””
    def _checklogin(request, *args, **kwargs):
        try:
            user_id = request.session[‘user_id’]
            if user_id:
                return view_func(request, *args, **kwargs)
            else:
                return redirect_to_login(request.path)
        except KeyError:
            return redirect_to_login(request.path)
    return _checklogin

redirect_to_login is also basically copied from the django auth code, but with one significant change. Before making this change, after a successful login, you would be redirected back to the login page, rather than the index page. Also, because the redirect was being cached by the proxy, attempts to access the index page directly would be redirected to the login page. I would call this a proxy bug, but polipo is pretty anal about standards-compliance. So this is the modified redirect_to_login:

def redirect_to_login(next):
    “Redirects the user to the login page, passing the given ‘next’ page”
    response = HttpResponseRedirect(‘/engulf/accounts/login/?%s=%s’ %
                                (REDIRECT_FIELD_NAME, next))
    response[‘Pragma’] = “no cache”
    response[‘Cache-Control’] = “no-cache”
    return response

Basically it is the same as the original, but inserts cache-control headers for both http 1.0 and 1.1. This prevents the proxy from cacheing the redirect, and my login decorator now works. I may post the login view and manipulator code at some point, because I think it’s a pretty good example of using a custom manipulator with a form that doesn’t directly affect a model.

Edit: Apologies for the curly quotes in the code samples. It’s being done by the Smartypants plugin for my blogging software, and to get it to stop, I need to turn it off entirely. It shouldn’t affect the version in the RSS feeds, though.

[ Posted: 08:47] | [ Category: ] | Permalink | Comments: 0 ]

 


Powered by PyBlosxom