确定django中会话的年龄

时间:2010-11-18 03:53:18

标签: django session django-views

如何在django中确定会话对象的年龄?

3 个答案:

答案 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))。

第一个显然是在查找期间。第二种情况发生在保存发生时,再次触发整个过程。

该怎么做?