Django:如何为匿名用户设置sessionid cookie而不使用SESSION\u SAVE\u EVERY\u请求

Django:如何为匿名用户设置sessionid cookie而不使用SESSION\u SAVE\u EVERY\u请求,django,session,session-cookies,anonymous-users,Django,Session,Session Cookies,Anonymous Users,我试图跟踪匿名用户,以确定他们何时第一次访问该网站,以及何时注册该网站 为此,我创建了一个具有相关功能的中间件,但这最初假设每个匿名用户已经有了一个与其关联的会话(即,sessionid cookie将在第一个响应中设置&关联的会话已经在django_会话中创建)。注意:存在会话应用程序和中间件 看起来情况并非如此,正如查看会话中间件一样,当匿名用户第一次出现在站点上时,会话从未被修改(用户会修改,因为设置了“\u auth\u user\u id”和“\u auth\u user\u back

我试图跟踪匿名用户,以确定他们何时第一次访问该网站,以及何时注册该网站

为此,我创建了一个具有相关功能的中间件,但这最初假设每个匿名用户已经有了一个与其关联的会话(即,sessionid cookie将在第一个响应中设置&关联的会话已经在django_会话中创建)。注意:存在会话应用程序和中间件

看起来情况并非如此,正如查看会话中间件一样,当匿名用户第一次出现在站点上时,会话从未被修改(用户会修改,因为设置了“\u auth\u user\u id”和“\u auth\u user\u backend”),因此从未被创建:

SessionMiddleware。处理\u响应

def process_response(self, request, response):
    """
    If request.session was modified, or if the configuration is to save the
    session every time, save the changes and set a session cookie.
    """
    try:
        accessed = request.session.accessed
        modified = request.session.modified
    except AttributeError:
        pass
    else:
        if accessed:
            patch_vary_headers(response, ('Cookie',))
        if modified or settings.SESSION_SAVE_EVERY_REQUEST:
            if request.session.get_expire_at_browser_close():
                max_age = None
                expires = None
            else:
                max_age = request.session.get_expiry_age()
                expires_time = time.time() + max_age
                expires = cookie_date(expires_time)
            # Save the session data and refresh the client cookie.
            request.session.save()
            response.set_cookie(settings.SESSION_COOKIE_NAME,
                    request.session.session_key, max_age=max_age,
                    expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                    path=settings.SESSION_COOKIE_PATH,
                    secure=settings.SESSION_COOKIE_SECURE or None,
                    httponly=settings.SESSION_COOKIE_HTTPONLY or None)
    return response

尝试1

为了尝试克服这一点,在我的中间件(位于会话中间件下方)中,我将强制会话上的save()来创建它:

if hasattr(request, 'session') and not request.session.session_key:
    request.session.save()
这将提供session_密钥,但不幸的是,当调用SessionMiddleware.process_响应时,request.session.modified仍然等于False,因此未设置sessionid cookie


尝试2

一种方法似乎是以任意方式修改会话,以确保SessionMiddleware.process\u响应中的
request.session.modified==True

if hasattr(request, 'session') and not request.session.session_key:
    request.session.save()
    request.session['some_variable'] = True
这似乎可以解决我的问题,而不必对每个请求都求助于
会话保存

问题

如何确保会话是为以前没有访问过的匿名用户创建的,而无需明确修改会话,或让
session\u SAVE\u EVERY\u REQUEST=True


谢谢你的帮助

即使显式修改会话也可能失败(例如将属性分配给会话属性)

您需要将
session.modified
显式设置为true

if hasattr(request, 'session') and not request.session.session_key:
    request.session.save()
    request.session.modified = True

查看会话保存时的对话。

谢谢Aidan,这非常有效。我仍然不清楚为什么会话模块不会创建会话,如果会话不存在,但只有在“修改”时才会创建会话…?是的,我知道你的意思。很高兴你把它整理好了。