django.contrib.sessions-SessionBase

SessionBase之因此可看成字典來操做,由於它自己就是對字典的包裝。因此須要瞭解一下python的一些魔法方法。python


舉個例子:瀏覽器

class DictWrapper:  
      def __init__(self):  
            self.dict = {}  
             
      def __getitem__(self, key):  
            return self.dict[key]  
            
      def __setitem__(self, key, value):  
            self.dict[key] = value
            
      def __delitem__(self, key):
            del self.dict[key]
            
      def __contains__(self, key):
        return key in self._session

__getitem__ 負責獲取數據。 緩存

__setitem__負責改變數據。cookie

__delitem__負責刪除數據。session

__contains__負責判斷是否包含這個key。app


而後看SessionBase的定義:
less

class SessionBase(object):
    """
    Base class for all Session classes.
    """
    TEST_COOKIE_NAME = 'testcookie'
    TEST_COOKIE_VALUE = 'worked'

    def __init__(self, session_key=None):
        self._session_key = session_key
        self.accessed = False
        self.modified = False
        self.serializer = import_string(settings.SESSION_SERIALIZER)

    def __contains__(self, key):
        return key in self._session

    def __getitem__(self, key):
        return self._session[key]

    def __setitem__(self, key, value):
        self._session[key] = value
        self.modified = True

    def __delitem__(self, key):
        del self._session[key]
        self.modified = True
        
    def get(self, key, default=None):
        return self._session.get(key, default)

    def pop(self, key, *args):
        self.modified = self.modified or key in self._session
        return self._session.pop(key, *args)
        
    def update(self, dict_):
        self._session.update(dict_)
        self.modified = True

    def has_key(self, key):
        return key in self._session

    def keys(self):
        return self._session.keys()

    def values(self):
        return self._session.values()

    def items(self):
        return self._session.items()

    def iterkeys(self):
        return self._session.iterkeys()

    def itervalues(self):
        return self._session.itervalues()

    def iteritems(self):
        return self._session.iteritems()

除了上述幾個魔法方法, SessionBase還實現了dict的其餘的方法。ide

基本上都是_session的包裝。函數


如今來看看_session的定義:性能

_session = property(_get_session)

_session的值是_get_session方法返回的。


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


_get_session方法會優先去獲取_session_cache這個緩存變量的值,若是沒有則調用load方法。

注意self.accessed屬性的改變。它會記錄是否獲取過session。



def load(self):
        """
        Loads the session data and returns a dictionary.
        """
        raise NotImplementedError('subclasses of SessionBase must provide a load() method')

load方法須要子類定義,返回session-data。

通常load實現要注意這種狀況,用戶第一次登錄是沒有_session_cache。注意_get_session方法,它會經過捕獲AttributeError異常,判斷是否存在_session_cache。若是沒有會調用load方法。

因此當用戶沒有_session_cache的時候,須要返回一個空字典。


注意一下clear的實現。由於執行clear函數時,若是self._session有可能會調用load函數,致使沒必要要的性能開銷。

因此直接複製_session_cache爲空。

def clear(self):
        # To avoid unnecessary persistent storage accesses, we set up the
        # internals directly (loading data wastes time, since we are going to
        # set it to an empty dict anyway).
        self._session_cache = {}
        self.accessed = True
        self.modified = True



由於session和cookie會有一個有效期,以'_session_expiry'存在_session_data裏。

def get_expiry_date(self, **kwargs):
        """Get session the expiry date (as a datetime object).

        Optionally, this function accepts `modification` and `expiry` keyword
        arguments specifying the modification and expiry of the session.
        """
        try:
            modification = kwargs['modification']
        except KeyError:
            modification = timezone.now()
        # Same comment as in get_expiry_age
        try:
            expiry = kwargs['expiry']
        except KeyError:
            expiry = self.get('_session_expiry')

        if isinstance(expiry, datetime):
            return expiry
        if not expiry:   # Checks both None and 0 cases
            expiry = settings.SESSION_COOKIE_AGE
        return modification + timedelta(seconds=expiry)

這裏注意_session_expiry對應的值,多是爲int,也多是datetime類型。若是爲int,則表示剩下的有效期,以second爲單位。若是爲datetime類型,則爲有效日期,須要計算二者的時間差,也是以second爲單位。 


get_expire_at_browser_close方法用來判斷session的截至時間是否爲關閉瀏覽器的時間。

當_session_expiry爲None而且settings.SESSION_EXPIRE_AT_BROWSER_CLOSE設置爲true,

_session_expiry爲0,

都會返回true。

def get_expire_at_browser_close(self):
        """
        Returns ``True`` if the session is set to expire when the browser
        closes, and ``False`` if there's an expiry date. Use
        ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry
        date/age, if there is one.
        """
        if self.get('_session_expiry') is None:
            return settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
        return self.get('_session_expiry') == 0
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息