I'm using Django and Redis as session engine (also Celery, but that is something else). It works perfectly and I can see an improvement in speed.
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
I have a script that runs every minute to check the active users through some methods and if the user hasn't been active in the latest minute, then the session gets removed. This is done for customer's tracking needs.
This script was working perfectly until I switched to Redis as a session engine. The session gets indeed removed from the DB but not from Redis. I'm not using any Django built-in method for this but my own function:
def clean_sessions():
stored_sessions = Session.objects.all()
active_users = active_users(minutes=1)
active_users_ids = [user.id for user in active_users]
for session in stored_sessions:
session_uid = session.get_decoded().get('_auth_user_id')
if not session_uid:
session.delete()
continue
if session_uid not in active_users_ids:
user = User.objects.get(pk=session_uid)
## some code between ##
session.delete()
My question is, how do I remove the session from the cache as well, so the user is actually logged out?
It wasn't very straightforward but I was able to fix it. I imported this from the file I have my clean_sessions():
from importlib import import_module
from django.conf import settings
Then, inside the function, I loaded the SessionStore object:
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
From there, it was very easy to remove the sessions, leaving the method like this:
def clean_sessions():
stored_sessions = Session.objects.all()
active_users = Request.objects.active_users(seconds=15)
active_users_ids = [user.id for user in active_users]
for session in stored_sessions:
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
s = SessionStore(session_key=session.session_key)
session_uid = session.get_decoded().get('_auth_user_id')
if not session_uid:
s.delete()
continue
if session_uid not in active_users_ids:
## some code ##
s.delete()
It's very important to load the right SessionStore from whatever session engine you're using, otherwise it will fail to remove it from both places (DB and cache).
In case someone else needs this for clearing all session data (e.g during tests) depending on backend In this case Redis and The database:
from django.conf import settings
from django_redis import get_redis_connection
from django.contrib.sessions.models import Session
REDIS = "django.contrib.sessions.backends.cache"
DATABASE = "django.contrib.sessions.backends.db"
REDIS_AND_DATABASE = "django.contrib.sessions.backends.cached_db"
def clear_all_session_data_globally():
"""
This will log out every user instantly and delete whatever they were working on, use with caution
:return:
"""
if settings.SESSION_ENGINE in [REDIS, REDIS_AND_DATABASE]:
# Warning this deletes everything from your cache, not just session data
get_redis_connection(getattr(settings, 'SESSION_CACHE_ALIAS', 'default')).flushall()
if settings.SESSION_ENGINE in [DATABASE, REDIS_AND_DATABASE]:
Session.objects.all().delete()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With