如何在django中确定会话对象的年龄?
答案 0 :(得分:2)
好的,这就是我想出的。好多了。我认为这与在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)
答案 1 :(得分:1)
您需要挂钩来自django.contrib.sessions.models.Session的post_init信号,以获得会话开始(或结束)的通知,然后将该信息保存到您自己的应用中的模型中。 e.g。
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对象。
答案 2 :(得分:0)
这是我最终做的而不是托马斯的建议。请注意,我拒绝使用接收器装饰器,因此在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))。
第一个显然是在查找期间。第二种情况发生在保存发生时,再次触发整个过程。
该怎么做?