Django:在同一 View 中设置 session 并获取 session key

标签 django django-models django-sessions

我想在数据库中存储一些东西,并使用当前 session 作为外键:
来自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))

要为此模型创建一个新条目,我使用以下内容来获取当前 session (在 views.py 中):
Session.objects.get(session_key=request.session.session_key)

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

我知道即使现在设置了 cookie,您仍然可以设置 session 对象。所以我可以想到一些技巧来完成这项工作,例如:
  • 将唯一标识符设置为 session 对象(除了 session key )
  • 将我希望添加到数据库的数据临时存储为 session 对象,并在使用 session 之前使用装饰器函数检查它是否存在。
  • 只需使用 session 对象,而不在数据库中存储任何内容(这在技术上是可行的,但对于我的实现,它将取决于 Python 字典 - 有几百个条目 - 在排序等方面至少与数据库一样有效。)


  • 但我想要一个我可以接受的更好的解决方案。这个问题有没有普遍使用或好的解决方案?或者我什至在我的模型中正确地引用了 session ?

    感谢您的帮助。

    最佳答案

    request.sessionSessionStore object具有唯一的 session_key。

    一旦访问该属性,就会创建 session_key。但是 session 对象本身只有在 View 处理完毕后(在 session 中间件的 process_response 方法中)才会通过调用 SessionStore 对象的 save 方法保存到数据库中。

    它并没有真正记录在案,但查看源代码我猜你应该创建一个新的 session 对象,如下所示:

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

    您还可以创建自定义 session 中间件,以确保您的新 session 对象在您的任何 View 尝试访问它之前始终可用:
    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 中的 SESSION_ENGINE 引用您的新 session 中间件)

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

    关于Django:在同一 View 中设置 session 并获取 session key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5130639/

    相关文章:

    python - Django 翻译 : can't find msguniq

    django - 以编程方式检查是否需要部署django南迁移

    python - 在 Django 中更改密码后自动注销/销毁 session

    python - 以特定的 json 格式发送报告

    django - django 中应用程序的媒体路径

    python - Django:在中间件中检索 session 或 cookie

    Django 中间件确定 session 中用户的组

    python - Django login_required 装饰器未将 "next"值传递给模板

    python - 为什么我需要在 Django 的 TestCase 中使用辅助方法 create_user() ?

    python-3.x - Django 上的 MakeMigration 错误 - ImportError : cannot import name 'FieldDoesNotExist' from 'django.db.models'