0

我试图了解会话在 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()都会sessionid从 cookie 中获取 ,然后SessionStore使用它创建一个新实例 sessionid

当我查看 and 的来源 __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已经存在。但这不应该是会话的全部意义吗——对于每个请求,Django 都需要在会话数据库中查找以查看会话是否已经存在?我猜这个数据库查找发生在某个地方,但我找不到它。

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

谢谢

4

1 回答 1

2

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)

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

x = request.session['key']

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

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

于 2011-05-12T23:10:02.503 回答