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) 

私がそれを正しく理解していれば、すべてのリクエスト は Cookie からSessionMiddleware.process_request()を取得し、sessionidそれを使用して新しいSessionStoreインスタンスを 作成しますsessionid

__init__()そして、 ofSessionStoreと のソースを見たとき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 でセッションがどのように機能するかを誤解していましたか?

ありがとう

4

1 に答える 1

2

SessionMiddlewareの3行目は、使用する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フルセッション用の軽量プロキシです。セッションIDCookieにエンコードされたキーに関連付けられたセッションオブジェクトに対してデータの読み取りまたは書き込みを行う必要がある場合にのみ、データベースにアクセスして完全なセッションになります。

于 2011-05-12T23:10:02.503 に答える