Django:在同一视图中设置会话并获取会话密钥 [英] Django: setting a session and getting session key in same view
问题描述
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设置,你仍然可以设置会话对象。所以我可以想到几个黑客做这个工作,例如:
- 将唯一标识符设置为会话对象(除了会话密钥)
- 临时存储要添加到数据库的会话对象的数据,并在使用会话之前使用decorator函数来检查是否存在。
- 只需使用会话对象,而不是在数据库中存储任何东西(这在技术上是可能的,但是对于我的实现,它将取决于Python字典 - 具有几百个条目 - 至少与数据库一样高效例如排序。)
但是我会像一个更好的解决方案,我可以住。这个问题有什么常用或者很好的解决方案吗?或者我甚至在我的模型中正确地引用会话?
感谢您的帮助。
request.session
是一个 SessionStore对象与唯一的session_key。
只要访问该属性,就会创建session_key。但是,会话对象本身仅在视图被处理之后才被保存到数据库(在会话中间件的process_response方法中),通过调用SessionStore对象的save方法。
没有真正的记录,但是看源代码我猜你应该创建一个新的会话对象,如下所示:
if not request.session.exists(request.session.session_key):
request.session.create()
您还可以创建自定义会话中间件,确保您的新会话对象在您的任何视图尝试访问之前始终可用:
<$ p $来自django.conf导入设置的$ p code从django.contrib.sessions.middleware导入
导入SessionMiddleware
class CustomSessionMiddleware(SessionMiddleware):
def process_request(self ,请求):
engine = import_module(settings.SESSION_ENGINE)
session_key = request.COOK IES.get(settings.SESSION_COOKIE_NAME,None)
request.session = engine.SessionStore(session_key)
如果没有request.session.exists(request.session.session_key):
request.session .create()
(当然你必须通过SESSION_ENIGNE在你的 settings.py
)
但请注意 - 如果用户的浏览器不会,这种方法将为每个请求生成一个新的会话对象支持cookies ...
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.
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 SESSION_ENIGNE 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 ...
这篇关于Django:在同一视图中设置会话并获取会话密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!