Django:设置会话并在相同视图中获取会话密钥

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (25)

我想将一些东西存储在数据库中,并将当前会话作为外键使用:from model s.py

class Visited(models.Model):
    session = models.ForeignKey(Session)
    page = models.ForeignKey(Page)
    times_visited = models.PositiveIntegerField()
    ip_address = models.IPAddressField()
    date_last_visited = models.DateTimeField()
    def __unicode__(self):
        return u'(%s, %s)' % (str(self.session.session_key), str(self.page.name))

为了为这个模型创建一个新条目,我使用以下方法获得当前会话(在views.py中):

Session.objects.get(session_key=request.session.session_key)

但是,如果这是用户第一次访问站点,因此还没有设置cookie,那么上面的代码将生成一个DoesNotExist错误。

我知道,即使现在有Cookie集,仍然可以设置会话对象。因此,我可以想出几个方法来完成这个工作,例如:

  • 将唯一标识符设置为会话对象(除会话键外)
  • 暂时存储我希望将会话对象添加到数据库中的数据,并在使用会话之前使用一个装饰函数来检查它是否存在。
  • 只需使用会话对象,而不将任何内容存储在数据库中(从技术上讲,这是可能的,但对于我的实现,它将依赖于Python字典--有几百个条目--至少与数据库一样高效)。

但我想要一个更好的解决方案。对于这一问题,是否有任何普遍使用的或好的解决办法?或者我在我的模型中正确地引用了会话吗?

谢谢你的帮助

提问于
用户回答回答于

request.sessionSessionStore对象有一个独特的session_key。

会议_一旦属性被访问,就会创建密钥。但是,会话对象本身仅在视图被处理后才保存到数据库中(在此过程中)。_通过调用SessionStore对象的Save方法来响应方法。

它并没有真正的文档化,但是看看源代码,我想应该创建一个新的Session对象,如下所示:

if not request.session.exists(request.session.session_key):
    request.session.create() 

还可以创建自定义会话中间件,确保在视图试图访问新会话对象之前始终可用:

from django.conf import settings
from django.contrib.sessions.middleware import SessionMiddleware

class CustomSessionMiddleware(SessionMiddleware):
    def process_request(self, request):
        engine = import_module(settings.SESSION_ENGINE)
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
        request.session = engine.SessionStore(session_key)
        if not request.session.exists(request.session.session_key):
            request.session.create() 

(当然,必须通过会话引用新的会话中间件。_在你的内心settings.py)

但是要注意,如果用户的浏览器不支持cookie,这种方法将为每个请求生成一个新的会话对象...

扫码关注云+社区