从Redis中删除会话(Django)

5

我正在使用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()

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

2个回答

2

虽然不是很容易,但我成功解决了问题。我从包含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非常重要,否则它将无法从两个位置(数据库和缓存)中删除。


1

如果有人需要在测试期间清除所有会话数据(例如,根据后端Redis和数据库),则可以使用以下内容:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接