巨大的Django Session表,正常行为还是bug?

Wol*_*lph 21 django django-sessions

也许这是完全正常的行为,但我觉得这个django_session表比它应该的大得多.

首先,我每天运行以下清理命令,因此大小不是过期的会话引起的:

DELETE FROM %s WHERE expire_date < NOW()
Run Code Online (Sandbox Code Playgroud)

数字:

  • 我们每天都有大约5000名独立访客(机器人除外).
  • SESSION_COOKIE_AGE被设置为默认,2周
  • 该表有超过1,000,000行

所以,我猜测Django还会为访问该网站的所有机器人生成会话密钥,并且机器人不会存储cookie,因此它会不断生成新的cookie.

但是......这是正常行为吗?是否有一个设置,以便Django不会为匿名用户生成会话,或者至少......没有使用会话的用户没有会话?

Wol*_*lph 17

经过一些调试后,我设法找出了问题的原因.我的一个中间件(以及我的大部分观点)中都有一个request.user.is_authenticated().

django.contrib.auth中间件套request.userLazyUser()

资料来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev = 14919#L13(我不明白为什么有return None那里,但好吧...... )

class AuthenticationMiddleware(object):
    def process_request(self, request):
        assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
        request.__class__.user = LazyUser()
        return None
Run Code Online (Sandbox Code Playgroud)

获取用户的LazyUser电话get_user(request):

来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev = 14919#L5

class LazyUser(object):
    def __get__(self, request, obj_type=None):
        if not hasattr(request, '_cached_user'):
            from django.contrib.auth import get_user
            request._cached_user = get_user(request)
       return request._cached_user
Run Code Online (Sandbox Code Playgroud)

get_user(request)方法做了user_id = request.session[SESSION_KEY]

来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/ 初始化?的.py修订版= 14919#L100

def get_user(request):
    from django.contrib.auth.models import AnonymousUser
    try:
        user_id = request.session[SESSION_KEY]
        backend_path = request.session[BACKEND_SESSION_KEY]
        backend = load_backend(backend_path)
        user = backend.get_user(user_id) or AnonymousUser()
    except KeyError:
        user = AnonymousUser()
    return user
Run Code Online (Sandbox Code Playgroud)

访问会话时设置accessed为true:

来源:http://code.djangoproject.com/browser/django/trunk/django/contrib/sessions/backends/base.py?rev=14919#L183

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
Run Code Online (Sandbox Code Playgroud)

这会导致会话初始化.该错误是由错误的会话后端引起的,当accessed设置为true 时也会生成会话...