【问题标题】:Django: at what point does SessionMiddleware check the database to see if a session is already in existence?Django:SessionMiddleware 在什么时候检查数据库以查看会话是否已经存在?
【发布时间】:2011-05-13 07:10:02
【问题描述】:

我试图了解会话在 Django 中是如何工作的。看SessionMiddleware的源码:

class SessionMiddleware(object): 
    def process_request(self, request): 
        engine = import_module(settings.SESSION_ENGINE) 
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) 
        request.session = engine.SessionStore(session_key) 

如果我理解正确,对于每个请求 SessionMiddleware.process_request() 将从 cookie,然后使用它创建一个新的SessionStore 实例 sessionid

当我查看__init__()SessionStoreSessionBase

  class SessionStore(SessionBase): 
      def __init__(self, session_key=None): 
          super(SessionStore, self).__init__(session_key) 

  class SessionBase(object): 
      def __init__(self, session_key=None): 
          self._session_key = session_key 
          self.accessed = False 
          self.modified = False 

所以基本上SessionStore 只是创建一个新实例而不尝试 在数据库中查找指定sessionid 的会话是否已存在 或不。但这不应该是整个会议的重点吗——对于每个 request Django 需要在 session 数据库中查找以查看是否 会话已经存在?我猜在某个地方这个数据库查找 发生但我找不到它。

你能告诉我在哪里可以找到它吗?还是我误解了如何 Django 中的会话工作?

谢谢

【问题讨论】:

    标签: django session django-sessions


    【解决方案1】:

    SessionMiddleware 的第三行调用一个特定的会话引擎,它规定了使用哪个 SessionStore。

    如果您进入 contrib/sessions/backends/base.py,您将看到以下代码:

    class SessionBase(object):
    
        ...
    
        def __getitem__(self, key):
            return self._session[key]
    
        def _get_session(self, no_load=False):
            """
            Lazily loads session from storage (unless "no_load" is True, when only
            an empty dict is stored) and stores it in the current instance.
            """
            self.accessed = True
            try:
                return self._session_cache
            except AttributeError:
                if self._session_key is None or no_load:
                    self._session_cache = {}
                else:
                    self._session_cache = self.load()
            return self._session_cache
    
        _session = property(_get_session)
    

    这样做是创建一个会话 proxy 对象,中间件已将其附加到请求上。它不会从数据库中加载会话对象,直到您说:

    x = request.session['key']
    

    此时,__getitem__(self, key) 尝试取消引用 self._session,后者(作为属性)反过来返回此事务的会话字典的缓存副本,或者如果没有可用的缓存,则从存储中获取它使用load() 方法。 load()方法由具体的子引擎实现:数据库、文件、缓存、缓存+db等。

    SessionStore 是一个完整会话的轻量级代理;只有当您需要读取或写入与会话 id cookie 中编码的键关联的会话对象时,它才会成为一个完整会话,访问数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2020-02-04
      • 2015-07-12
      • 2014-04-10
      相关资源
      最近更新 更多