26

我想在数据库中存储一些东西,并使用当前会话作为外键:来自 models.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 字典 - 有几百个条目 - 至少与数据库一样高效,用于排序之类的事情。)


但我想要一个更好的解决方案,我可以忍受。这个问题有没有普遍使用或好的解决方案?还是我什至在我的模型中正确引用了会话?

感谢您的帮助。

4

2 回答 2

58

request.session是 具有唯一 session_key的SessionStore 对象。

session_key 在属性被访问后立即创建。但是会话对象本身只有在视图被处理后(在会话中间件的 process_response 方法中)通过调用 SessionStore 对象的保存方法保存到数据库中。

它并没有真正记录在案,但是查看源代码我猜您应该像这样创建一个新的会话对象:

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() 

(当然你必须通过你的 SESSION_ENGINE 引用你的新会话中间件settings.py

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

于 2011-02-27T04:19:54.963 回答
1

如果你想破坏会话,我建议一个更好的主意是首先使用 django shell。

from django.contrib.sessions.models import Session
Session.objects.all() #you see all sessions
Session.objects.all().delete() 

在最后一个查询中,您可以根据需要进行过滤。并点击查询

于 2018-06-07T09:30:01.950 回答