Определить возраст сеанса в Джанго - PullRequest
4 голосов
/ 18 ноября 2010

Как определить возраст объекта сеанса в django?

Ответы [ 3 ]

2 голосов
/ 08 января 2011

ОК, вот что я придумала.Намного лучше.Я думаю, что это так же дешево, как использование post_save для объекта Session:

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 голос
/ 18 ноября 2010

вам потребуется перехватить сигнал post_init, поступающий от django.contrib.sessions.models.Session, чтобы получить уведомление о начале (или конце) сеанса, а затем сохранить эту информацию в модели в вашем собственном приложении. например,

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, представляющий возраст сеанса.

0 голосов
/ 08 января 2011

Вот что я в итоге сделал вместо предложения Томаса. Обратите внимание, что я отказался использовать декоратор приемника, чтобы он все еще работал до версии 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)) каждый раз, когда сеанс изменяется.

Первый явно во время поиска. Второе происходит, когда происходит сохранение, снова вызывая весь процесс.

Что делать вместо этого?

...