Django: в какой момент SessionMiddleware проверяет базу данных, чтобы увидеть, существует ли уже сеанс? - PullRequest
0 голосов
/ 13 мая 2011

Я пытаюсь понять, как работает сессия в 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 или нет. Но не в этом ли смысл всей сессии - это для каждого запрос Django должен искать в базе данных сеанса, чтобы увидеть, если сессия уже есть? Я предполагаю, что в каком-то месте этот поиск в базе данных имеет место, но я не могу его найти.

Можете ли вы сказать мне, где я могу его найти? Или я неправильно понял, как сеансовая работа в Джанго?

Спасибо

1 Ответ

2 голосов
/ 13 мая 2011

Третья строка SessionMiddleware вызывает конкретный механизм сессии , который указывает, какой SessionStore использовать.

Если вы зайдете в contrib / session / 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() реализуется определенными дочерними механизмами: база данных, файл, кэш, кэш + БД и т. Д.

SessionStore - облегченный прокси для полного сеанса; он становится полным сеансом, попадающим в базу данных, когда вам нужно прочитать или записать данные в объект сеанса, связанный с ключом, закодированным в файле cookie идентификатора сеанса.

...