我正在尝试理解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
。
当我查看__init__()
SessionStore
和SessionBase
的来源时
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
只是在不尝试的情况下创建一个新实例
在数据库中查找以查看是否已存在具有指定{{1}}的会话
或不。但不应该是整个会话点 - 对每一个人来说都是如此
请求Django需要在会话数据库中查找是否存在
会话已经存在?我在某个地方猜测这个数据库查找
发生了,但我找不到它。
你能告诉我在哪里可以找到它吗?或者我误解了如何 在Django会议工作?
由于
答案 0 :(得分: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._session
,其(作为属性)依次返回此事务的会话字典的缓存副本,或者如果没有可用的缓存,则提取它使用load()
方法从商店中获取。 load()
方法由特定的子引擎实现:数据库,文件,缓存,缓存+数据库等。
SessionStore
是完整会话的轻量级代理;当您需要读取或写入与会话ID cookie中编码的密钥关联的会话对象的数据时,它只会成为一个完整的会话,命中数据库。