Before marked as dup (I believe many answers are incorrect becase): According to my research:
request.session.get_expiry_age
returns the TOTAL lifespan of the cookie, not the time from now until it expires. It always returns the same value, irrespecitive of how much time is left.get_expiry_date
adds the total lifespan to the now time. It always increases when called.
Hence niether of them help.settings.SESSION_SAVE_EVERY_REQUEST
refreshes the cookie on every request, this is NOT what I am trying to achieve.
get_session_cookie_age()
ONLY returns the value of settings.SESSION_COOKIE_AGE, as seen in the sourcecode:
def get_session_cookie_age(self):
return settings.SESSION_COOKIE_AGE
I use the cached_db
session back end. The cached part is made none in void because it has to save the cookie everytime, hence SESSION_SAVE_EVERY_REQUEST
is not applicable. The reason I ask this question is because I wish to refresh a cookie ONLY if the time left has gone below a threshold, and hence have some hysterious (have the benefits of caching and auto refreshing).
Here is my code that does not work because of the behaviour of get_expiry_age
/get_expiry_date
as explained above:
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
class SessionExpiry(MiddlewareMixin):
def process_request(self, request):
"""Automatically refresh a session expirary at a certain limit.
If request.session age goes below settings.SESSION_REFRESH, then
set the sessions expirary age to settings.SESSION_COOKIE_AGE. The
session is not refreshed every time to have the caching benefits of
the cached_db backend.
"""
try:
empty = request.session.is_empty()
except AttributeError:
return None
if (empty or not getattr(settings, 'SESSION_REFRESH', None)):
return None
if request.session.get_expiry_age() < settings.SESSION_REFRESH:
request.session.set_expiry(settings.SESSION_COOKIE_AGE)
return None
This is an area of Django that's confusing, in both design and documentation. The easiest way to figure out what's going on is to look at the source code.
To get what you want you need to set a custom expiration as a datetime
. If you use seconds (including the default SESSION_COOKIE_AGE
) that is interpreted as the number of seconds from now; that is, from whenever you ask.
So to set the expiration, use:
# Using timedelta will cause the session to save the expiration time as a datetime.
request.session.set_expiry(timedelta(seconds=settings.SESSION_COOKIE_AGE))
If you do that, calls to get_expiry_age()
will return the actual difference between the current datetime and the datetime set as the expiry.
Be sure to note the warning in the set_expiry()
documentation: "Note that datetime
and timedelta
values are only serializable if you are using the PickleSerializer
."