【问题标题】:Django check session without creating it in datebaseDjango检查会话而不在数据库中创建它
【发布时间】:2014-08-24 04:44:29
【问题描述】:

我通常这样检查会话:

if request.session.get('var', False):  
  ...

唯一的问题是,如果我这样做并且会话不存在,django 会创建它 - 向 django_session 表添加一行。
如果会话不存在,如何在不创建会话的情况下执行此检查?

【问题讨论】:

标签: python django session


【解决方案1】:

默认情况下,会话后端以获取或创建方式处理会话。鉴于您使用的是数据库后端,您可以将访问包装在 atomic 语句中,以便在未找到数据时自动回滚:

try:
    with transaction.atomic():
        var = request.session['var']
except KeyError:
    var = False

编辑:

如果你不能让它工作(虽然我很好奇为什么不能工作),你可以尝试以下方法来访问会话数据而不触发_get_session 方法:

try:
    var = request.session._session_cache['var']
except AttributeError:
    try:
        s = Session.objects.get(
            session_key=self.session_key,
            expire_date__gt=timezone.now()
        )
        request.session._session_cache = self.decode(s.session_data)
        var = request.session._session_cache['var']
    except (Session.DoesNotExist, SuspicousOperation, KeyError):
        var = False
except KeyError
    var = False

Django SessionStore 对象(可通过 request.session 访问)实现字典接口并利用内部缓存。所有正常的字典访问都使用_session 属性,该属性尝试访问内部缓存,如果失败,则创建一个新的会话对象并将其存储在数据库中。通过直接访问内部缓存 (session._session_cache),您可以跳过该属性,如果失败,会话后端不会自动创建新会话。这正是 Django 内部所做的,当它不存在时不会创建新的会话对象。

【讨论】:

  • 对我不起作用。而且,这个方法是不是还是会保存到数据库再恢复?我可以只检查会话而不创建它吗?
  • 如果您删除 try/except,它会引发 KeyError 吗?如果没有会话并且您尝试访问它,则后端本身会创建会话。您可以使用自定义 load 方法创建自己的后端。
  • 是的,它确实会引发 KeyError。而且,当这种情况发生时,回滚确实按预期工作 - 没有数据保存在数据库中。但是,如果我“捕获”异常,数据库中仍然会创建一个新行
  • 为了清楚起见,这是我的代码:try: with transaction.atomic(): request.session['userID'] except: pass return render(request, 'index.html', {} )
  • 无法做断线。只是想指出我没有犯在原子块内捕获异常的错误。我按照这里提到的做了:docs.djangoproject.com/en/1.6/topics/db/transactions/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多