【发布时间】:2011-05-11 19:48:28
【问题描述】:
如何确定 django 中会话对象的年龄?
【问题讨论】:
标签: django session django-views
如何确定 django 中会话对象的年龄?
【问题讨论】:
标签: django session django-views
您需要挂钩来自 django.contrib.sessions.models.Session 的 post_init 信号,以便收到会话开始(或结束)的通知,然后将该信息保存到您自己应用程序中的模型中。例如
from django.contrib.sessions.models import Session
from django.db.models import *
from django.db.models.signals import post_init, pre_delete
from django.dispatch import receiver
from datetime import datetime
class SessionTimer(Session):
#note: a OneToOneField with the name 'session' has been added as part of the inheritance
created = DateTimeField(auto_now_add=True) #joined field is auto initialized with creation time
def age(self):
return (datetime.now() - self.created)
@receiver(post_init, sender=Session)
def session_create_listener(instance, **kwargs):
created_session = instance
timer_entry = SessionTimer(session=created_session)
timer_entry.save()
@receiver(pre_delete, sender=Session)
def session_destroy_listener(instance, **kwargs):
SessionTimer.objects.get(session=instance).delete() # short version
因此,当您需要知道会话的年龄时,请使用session.sessiontimer.age()。这将返回一个表示会话年龄的 TimeDelta 对象。
【讨论】:
session_create_listener(instance, **kwargs)。现在应该是正确的。
这就是我最终做的,而不是 Thomas 的建议。请注意,我拒绝使用接收器装饰器,因此它在 1.3 之前仍然可以工作。
(这需要认真纠正)。
from django.db import models
from people.models import Member
from django.contrib.sessions.models import Session
from django.contrib.sessions.backends.db import SessionStore
from django.db.models import *
from django.db.models.signals import post_save, pre_delete, post_init
#from django.dispatch import receiver
from datetime import datetime
class SessionInfo(models.Model):
#note: a OneToOneField with the name 'session' has been added as part of the inheritance
created = models.DateTimeField(auto_now_add=True) #joined field is auto initialized with creation time
session = models.OneToOneField(Session)
def age(self):
return (datetime.now() - self.created)
def session_create_listener(instance, **kwargs):
store = SessionStore(session_key=instance.session_key)
if '_auth_user_id' in store:
try:
sessioninfo = SessionInfo.objects.get(session=instance)
except SessionInfo.DoesNotExist:
sessioninfo = SessionInfo(session=instance)
sessioninfo.save()
store['anonymous'] = False
store.save()
else:
try:
store['anonymous']
except KeyError:
store['anonymous'] = True
store.save()
post_save.connect(session_create_listener, sender=Session)
我希望有人可以为我纠正这个问题,因为我不敢相信这是最有效的方法。
首先,这会在每次修改会话时添加两个额外的数据库命中(在第一次尝试中:sessioninfo = SessionInfo.objects.get(session=instance))。
第一个显然是在查找期间。第二次发生在保存发生时,再次触发整个过程。
该怎么做?
【讨论】:
好的,这就是我想出的。好多了。我认为这与在 Session 对象上使用 post_save 一样便宜:
from django.db import models
from people.models import Member
from django.contrib.sessions.models import Session
from django.contrib.sessions.backends.db import SessionStore
from django.db.models import *
from django.db.models.signals import post_save, pre_delete, post_init
from datetime import datetime
class SessionInfo(models.Model):
#note: a OneToOneField with the name 'session' has been added as part of the inheritance
created = models.DateTimeField(auto_now_add=True) #joined field is auto initialized with creation time
session = models.OneToOneField(Session)
def age(self):
return (datetime.now() - self.created)
def session_create_listener(instance, **kwargs):
store = SessionStore(session_key=instance.session_key)
if '_auth_user_id' in store:
try:
instance.sessioninfo
except SessionInfo.DoesNotExist:
sessioninfo = SessionInfo(session=instance)
sessioninfo.save()
post_save.connect(session_create_listener, sender=Session)
【讨论】: