#django #session #django-sessions
#django #сеанс #django-сеансы
Вопрос:
Я пытаюсь понять, как работает сеанс в 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__()
of 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
или нет. Но разве не в этом должен быть весь смысл сеанса — в том, что для каждого
запрос Django необходимо просмотреть в базе данных сеанса, чтобы увидеть, существует ли
сеанс уже существует? Я предполагаю, что в каком-то месте этот поиск по базе данных
происходит, но я не могу его найти.
Не могли бы вы сказать мне, где я могу это найти? Или я неправильно понял, как работает сеанс в Django?
Спасибо
Ответ №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)
Что это делает, так это создает объект session proxy, который промежуточное программное обеспечение прикрепило к запросу. Он не загружает объект сеанса из базы данных, пока вы не скажете:
x = request.session['key']
В этот момент программа __getitem__(self, key)
пытается выполнить разыменование self._session
, которое (будучи свойством), в свою очередь, возвращает кэшированную копию словаря сеанса для этой транзакции, или, если кэш недоступен, извлекает его из хранилища с помощью load()
метода. load()
Метод реализуется конкретными дочерними движками: database, file, cache, cache db и т.д.
SessionStore
это облегченный прокси-сервер для полного сеанса; он становится полным сеансом, попадая в базу данных, только когда вам нужно прочитать или записать данные в объект сеанса, связанный с ключом, закодированным в cookie идентификатора сеанса.