在视图外使用Django会话

2018-03-12  本文已影响12人  大爷的二舅

本节中的示例直接从django.contrib.sessions.backends.db后端导入SessionStore对象。 在你自己的代码中,你应该考虑从SESSION_ENGINE指定的会话引擎中导入SessionStore,如下所示:

>>> from importlib import import_module
>>> from django.conf import settings
>>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore 

API可用于在视图之外操作会话数据:

>>> from django.contrib.sessions.backends.db import SessionStore
>>> s = SessionStore()
>>> # stored as seconds since epoch since datetimes are not serializable in JSON.
>>> s['last_login'] = 1376587691
>>> s.save()
>>> s.session_key
'2b1189a188b44ad18c35e113ac6ceead'

>>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
>>> s['last_login']
1376587691 

为了减轻会话修复攻击,会重新生成不存在的会话密钥:

>>> from django.contrib.sessions.backends.db import SessionStore
>>> s = SessionStore(session_key='no-such-session-here')
>>> s.save()
>>> s.session_key
'ff882814010ccbc3c870523934fee5a2'

如果你使用django.contrib.sessions.backends.db后端,每个会话只是一个普通的Django模型。 会话模型在django / contrib / sessions / models.py中定义。 因为这是一个普通的模型,所以可以使用普通的Django数据库API访问会话:

>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)

请注意,您需要调用get_decoded()来获取会话字典。 这是必要的,因为字典以编码格式存储:

>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
会话保存

默认情况下,当会话被修改时,Django仅保存到会话数据库 - 即如果任何字典值已被分配或删除:

# Session is modified.
request.session['foo'] = 'bar'

# Session is modified.
del request.session['foo']

# Session is modified.
request.session['foo'] = {}

# Gotcha: Session is NOT modified, because this alters
# request.session['foo'] instead of request.session.
request.session['foo']['bar'] = 'baz'

在上例的最后一种情况下,我们可以通过在会话对象上设置修改后的属性来显式地告诉会话对象它已被修改:

request.session.modified = True 

要更改此默认行为,请将SESSION_SAVE_EVERY_REQUEST设置设置为True。当设置为True时,Django会在每个请求中将会话保存到数据库。请注意,会话cookie仅在创建或修改会话时发送。如果SESSION_SAVE_EVERY_REQUEST为真,会话cookie将在每个请求中发送。同样,每次会话cookie发送时,会话cookie的expires部分都会更新。如果响应的状态码是500,则会话不会被保存。

浏览器长度会话比持久会议

您可以通过SESSION_EXPIRE_AT_BROWSER_CLOSE设置来控制会话框架是使用浏览器长度会话还是持久会话。默认情况下,SESSION_EXPIRE_AT_BROWSER_CLOSE设置为False,这意味着会话Cookie将存储在用户浏览器中的时间长达SESSION_COOKIE_AGE。如果您不希望每次打开浏览器时都必须登录,请使用此选项。

如果SESSION_EXPIRE_AT_BROWSER_CLOSE设置为True,则Django将使用浏览器长度的cookie - 一旦用户关闭浏览器就会过期的cookie。

某些浏览器(例如Chrome)提供的设置允许用户在关闭并重新打开浏览器后继续浏览会话。 在某些情况下,这可能会干扰SESSION_EXPIRE_AT_BROWSER_CLOSE设置并阻止会话在浏览器关闭时过期。 在测试启用了SESSION_EXPIRE_AT_BROWSER_CLOSE设置的Django应用程序时请注意这一点。

清除会话存储

随着用户在您的网站上创建新会话,会话数据可能会累积到您的会话存储中。 Django不提供自动清除过期会话。 因此,您的工作是定期清除过期的会话。 Django为此提供了清理管理命令:clearsessions。 建议定期调用此命令,例如作为每日cron作业。

请注意,缓存后端不容易出现此问题,因为缓存会自动删除陈旧的数据。 Cookie后端也不是,因为会话数据是由用户的浏览器存储的。

下一步是什么

接下来,我们将通过检查Django的缓存后端来继续关注更高级的Django主题。

上一篇下一篇

猜你喜欢

热点阅读