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

发布于 2024-10-19 09:39:26 字数 1007 浏览 1 评论 0原文

我想在数据库中存储一些内容,并使用当前会话作为外键: 为了为此模型

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设置你仍然可以设置session对象。因此,我可以想到一些技巧来完成这项工作,例如:

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


但我想要一个我可以接受的更好的解决方案。对于这个问题,有没有什么常用的或者好的解决方案呢?或者我是否在模型中正确引用了会话?

感谢您的帮助。

I want to store some things in a database, and am using the current session as a foreign key:
from 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))

To make a new entry for this model I'm using the following to get the current session (in views.py):

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

However if it is the first time a user has visited the site, and thus do not have a cookie set yet, the code above will produce a DoesNotExist error.

I know that even if there is now cookie set you can still set session objects. So I can think of a few hacks to make this work, such as:

  • Set unique identifier as a session object (in addition to the session key)
  • Temporarily store the data I wish to add to the database a session object, and use a decorator function to check if it exists before using a session.
  • Just use the session objects and not store anything in the database (this would be technically possible, but for my implementation it would depend on Python dictionaries -with a few hundred entries- being at least as efficient as a database for things like sorting.)

But I would like a better solution I can live with. Are there any generally used or good solutions to this problem? Or am I even referencing sessions properly in my model?

Thank you for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-10-26 09:39:26

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

一旦访问该属性,就会创建 session_key。但会话对象本身仅在视图被处理后(在会话中间件的 process_response 方法中)通过调用 SessionStore 对象的 save 方法保存到数据库中。

它没有真正记录下来,但查看源代码,我想您应该创建一个新的会话对象,如下所示:

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 中的 SESSION_ENGINE 引用新的会话中间件)

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

request.session is a SessionStore object with a unique session_key.

The session_key is created as soon as the attribute is accessed. But the session object itself is only saved to the database after the view has been processed (in the process_response method of the session middleware) by calling the save method of the SessionStore object.

It's not really documented, but looking at the source code I guess you are supposed to create a new session object like this:

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

You could also create custom session middleware, that makes sure your new session object is always available before any of your views tries to access it:

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

(Of course you must reference your new session middleware via the SESSION_ENGINE inside your settings.py)

But be aware - this approach will generate a new session object for every request if the user's browser does not support cookies ...

看海 2024-10-26 09:39:26

如果你想销毁会话,我建议更好的主意是首先使用 django shell。

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

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

if you want to destroy session i would suggest a better idea is first use django shell.

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

in last query you can filter according to your need. and hit a query

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文