I\'m running Django 1.3, using Sessions Middleware and Auth Middleware:
# settings.py
SESSION_ENGINE = django.contrib.sessions.backends.db # Persist sessions
This is not a direct answer, but it solves your problem and reduces DB hits to zero. With recent versions of Django you can use the cookie based session backend:
https://docs.djangoproject.com/en/dev/topics/http/sessions/#cookie-session-backend
Another version of a function using list comprehension that will just straight up delete every unexpired session of a user:
from django.utils import timezone
from django.contrib.sessions.models import Session
def delete_all_unexpired_sessions_for_user(user):
unexpired_sessions = Session.objects.filter(expire_date__gte=timezone.now())
[
session.delete() for session in unexpired_sessions
if str(user.pk) == session.get_decoded().get('_auth_user_id')
]
If you return a QuerySet from your all_unexpired_sessions_for_user
function, you could limit your database hits to two:
def all_unexpired_sessions_for_user(user):
user_sessions = []
all_sessions = Session.objects.filter(expire_date__gte=datetime.datetime.now())
for session in all_sessions:
session_data = session.get_decoded()
if user.pk == session_data.get('_auth_user_id'):
user_sessions.append(session.pk)
return Session.objects.filter(pk__in=user_sessions)
def delete_all_unexpired_sessions_for_user(user, session_to_omit=None):
session_list = all_unexpired_sessions_for_user(user)
if session_to_omit is not None:
session_list.exclude(session_key=session_to_omit.session_key)
session_list.delete()
This gives you a total of two hits to the database. Once to loop over all of the Session
objects, and once to delete all of the sessions. Unfortunately, I don't know of a more direct way to filter through the sessions themselves.
It might be helpful to use:
The most efficient way is to store the session id of the user during login. You can access the session ID using request.session._session_key and store it in a separate model which has reference to the user. Now when you want to remove all the sessions of the user, just query this model which will return all the active sessions for the user in question. Now you need to delete only these sessions from the session table. Much better than having to look up all the sessions to filter out just sessions for a particular user.