2010-11-18 13 views

答えて

2

OK、これは私が思いついたものです。ずっといい。私はこれを取得する予定です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) 
+0

私の答えをはがし、あなたのことを正しいものにしてください。高級 – Thomas

+0

あなたは冗談ですか?あなたの答えは間違っていた。うまく行かなかった。私はそれについてコメントし、あなた(または他の誰か)がそれを修正するために1週間待った。あなたはしませんでした。私は踏み込んで、問題とその解決方法を見つけました。実際に動作し、エラーを発生させないコードを投稿しました。正解の最小要件だとは思いませんか?あなたの答えが間違っていて間違っているにもかかわらず、私はまだそれに投票しましたが、正解をマークして他の視聴者に彼らのアプリがうまくいかない理由を頭で傷つけることを正当化することはできません。 – jMyles

1

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オブジェクトを返します。

+0

このコードは動作しません、いくつかの理由のために:1)少なくとも輸入、「受信機」の中で間違ったスペルがデコレータ。 2).save()メソッドを実行すると、session_create_listener関数が実際にセッションを保存して再帰的ループを引き起こしているようです。 3)オブジェクト "created_session"は、 ""であり、Sessionインスタンスではありません。したがって、ValueErrorが発生します。 – jMyles

+0

私はsession_create_listener(インスタンス、** kwargs)の代わりにsession_create_listener(セッション、** kwargs) 'を使っていました。今は正しいはずです。 – Thomas

+0

これは解決策に取り組む人々にとって実行可能で興味深いコードですが、それ自体は一つではありません。あなたはなぜpost_saveの代わりにpost_initを使用していますか?また、SessionTimer自体がシグナルを発生させる原因は何ですか? – jMyles

0

ここで私は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) 

これを行うには、これが最も効果的な方法だとは思えないので、誰かが私のためにこれを修正できることを願っています。

まず、セッションが変更されるたびに2つの追加のデータベースヒット(最初のtry:sessioninfo = SessionInfo.objects.get(session = instance))が追加されます。

最初は明らかにルックアップ中です。セーブが発生すると、2番目の処理が実行され、プロセス全体が再びトリガされます。

代わりに何をしますか?

関連する問題