一尘不染

从Redis删除会话(Django)

redis

我正在使用Django和Redis作为会话引擎(也是Celery,但这是其他东西)。它运行完美,我可以看到速度有所提高。

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

我有一个脚本,每分钟运行一次,以通过某些方法检查活动用户,如果该用户在最近一分钟内未处于活动状态,则该会话将被删除。这样做是为了满足客户的跟踪需求。

在我切换到Redis作为会话引擎之前,该脚本运行良好。实际上,该会话确实已从数据库中删除,但未从Redis中删除。我没有为此使用任何Django内置方法,而是使用了自己的函数:

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()

我的问题是,如何从缓存中也删除会话,以便实际上注销用户?


阅读 684

收藏
2020-06-20

共1个答案

一尘不染

它不是很简单,但是我能够解决它。我从我有clean_sessions()的文件中导入了此文件:

from importlib import import_module
from django.conf import settings

然后,在函数内部,我加载了SessionStore对象:

SessionStore = import_module(settings.SESSION_ENGINE).SessionStore

从那里开始,删除会话非常容易,留下这样的方法:

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()

从正在使用的任何会话引擎中加载正确的SessionStore非常重要,否则它将无法从两个位置(数据库和缓存)中将其删除。

2020-06-20