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
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息