18

From django's documentation, I became under the impression that calling:

request.session.set_expiry(300)

from one view would cause the session to expire after five minutes inactivity; however, this is not the behavior that I'm experiencing in django trunk. If I call this method from one view, and browse around to other views that don't call the method, the session expires in five minutes. The behavior that I was expecting was an expiry only after five minutes of inactivity and not simply failing to call set_expiry again before the expiry.

My question then is do I really need to call set_expiry in every view? If so, does there exist some decorator that may be of assistance? I can't imagine this isn't part of contrib.

Thanks, Pete

3 Answers 3

33

As the author of those methods, I can see that the documentation isn't very clear regarding this. Your observations are correct: only requests which cause the session to be altered is considered "activity".

You can use the SESSION_SAVE_EVERY_REQUEST setting to get the behavior you're after (at the obvious cost of the session having to being saved every request).

Note : It will update the existing session record with latest expiry date.

2
  • Thanks Chris, that did it. The information that you just provided should be included in the docs.
    – slypete
    Commented Sep 3, 2009 at 5:07
  • 2
    Agreed. Care to open a ticket? ;) Commented Sep 4, 2009 at 4:00
4

A simple middleware would probably do better than setting this up in every view. This is what I used.

class SessionExpiry(object):
    """ Set the session expiry according to settings """
    def process_request(self, request):
        if getattr(settings, 'SESSION_EXPIRY', None):
            request.session.set_expiry(settings.SESSION_EXPIRY)
        return None

This depends on SESSION_EXPIRY being set in your config. It's format is the same as request.session.set_expiry.

MIDDLEWARE_CLASSES should be defined with this order in mind:

MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    '<yourproject>.<yourapp>.middleware.SessionExpiry',
    ...
}

It'd be nice if django.contrib.sessions took this setting into account by default.

7
  • Did you miss SmileyChris' answer? SESSION_SAVE_EVERY_REQUEST does exactly this without any custom middleware.
    – slypete
    Commented Oct 28, 2012 at 3:53
  • 2
    Yes, but only having set_expiry called in one view requires all your users to hit that specific view(s) that sets the expiry. It's unlikely your users will funnel through a this specific view. With the middleware you can abstract this expiration set outside of a view. If his answer works for you, cool. I just thought this might be a cleaner way of doing it and it's the way I chose to go about it. Commented Oct 28, 2012 at 16:47
  • I think you misunderstood the answer. SESSION_SAVE_EVERY_REQUEST does exactly what you're doing without any view specific code. I'm just pointing out that you reinvented the wheel.
    – slypete
    Commented Oct 28, 2012 at 20:36
  • 2
    That setting forces expiry to be updated, yes, but it doesn't set the expiry. So no, it doesn't do exactly the same thing. My middleware allows you to set the expiry to an arbitrary value. Commented Oct 29, 2012 at 18:35
  • 3
    While SESSION_SAVE_EVERY_REQUEST is useful if you want a global expire policy, defining a custom middleware allows you to customize it more. For instance, if the request is coming from an IP the user marked as "trusted", it can set it to never expire (or to a very long value, updated at every request). Otherwise, it can set it to a short value. Etc. So it's not exactly "reinventing the wheel", but an alternative method that can be useful in some circumstances.
    – mgibsonbr
    Commented Feb 17, 2013 at 0:21
0

If you set "True" to SESSION_SAVE_EVERY_REQUEST on "settings.py" as shown below, automatically, session is updated every time the current page is reopened or other page is opened in Django Website.

SESSION_SAVE_EVERY_REQUEST = True # False by default

For example, session expires in 15 minutes. Then, from 3:00 pm, a session starts by logging in the page in Django Website so the session expires at 3:15 pm. Then, at 3:10 pm, the current page is reopened or other page is opened in Django Website so the session is updated so the new session expires at 3:25 pm which means you are logged in until 3:25 pm, so in other words, if the current page is not reopened or other page is not opened in Django Website then the new session expires at 3:25 pm which means you are logged out at 3:25 pm so you need to log in again to the page in Django Website to start a new session.

Not the answer you're looking for? Browse other questions tagged or ask your own question.