代码之家  ›  专栏  ›  技术社区  ›  jMyles

确定在Django的一个疗程的年龄

  •  4
  • jMyles  · 技术社区  · 14 年前

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

    3 回复  |  直到 14 年前
        1
  •  2
  •   jMyles    14 年前

    好吧,这就是我想出来的。好多了。我认为这和在会话对象上使用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)
    
        2
  •  1
  •   Thomas    14 年前

    您需要挂接来自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对象。

        3
  •  0
  •   jMyles    14 年前

    这是我最后做的而不是托马斯的建议。请注意,我拒绝使用接收器装饰器,这样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))。

    第一个显然是在查找过程中。第二次发生在保存发生时,再次触发整个过程。

    怎么办?