代码之家  ›  专栏  ›  技术社区  ›  Bob Dem

从Redis(Django)中删除会话

  •  5
  • Bob Dem  · 技术社区  · 10 年前

    我使用Django和Redis作为会话引擎(也使用Celery,但这是另一回事)。它工作得很好,我可以看到速度的提高。

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

    我有一个脚本,它每分钟运行一次,通过一些方法检查活动用户,如果用户在最近一分钟内没有活动,那么会话将被删除。这是为了满足客户的跟踪需求。

    在我切换到Redis作为会话引擎之前,这个脚本一直运行得很好。会话确实会从DB中删除,但不会从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 回复  |  直到 10 年前
        1
  •  2
  •   smac89    3 年前

    这不是很简单,但我能够修复它。我从我有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非常重要,否则它将无法从两个位置(DB和缓存)删除它。

        2
  •  1
  •   Aaron McMillin    4 年前

    如果其他人需要此选项来清除所有会话数据(例如在测试期间),具体取决于后端 在这种情况下,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()