2011-11-15 4 views
0

ユーザーのWebページで、クラス "ModelClass"のインスタンスに関する一般的な統計情報を表示したいとします。数千のModelClassオブジェクトがあり、計算に必要な統計量が多いとします。私はモデルマネージャでこれを行うことができますことを考え出し、ここで(非常に)簡単な例でいる:データベースへのdjangoモデルマネージャーの結果の保存

class ModelClassCustomManager(models.Manager): 
    def get_query_set(self): 
     return super(ModelClassCustomManager, self).get_query_set().filter(is_complete = True) 


class ModelClass(models.Model): 
    is_complete = models.BooleanField(default = False) 
    ... 
    objects = models.Manager() 
    complete_objects = ModelClassCustomManager() 

私の関心は、ユーザーがページを表示するときに、これが計算されている場合、これは多くのリソースを消耗ということです。したがって、統計が実際に変更される唯一の時間なので、新しいModelClassオブジェクトを変更または作成する場合にのみ計算したいと思います。これはModelClassのsave()メソッドをオーバーライドすることで行うことができます。

これらの結果を保存するにはどうすればよいですか?計算された統計を保持するための別のジャンゴモデルを作成すべきか、あるいはこの情報を格納する別の方法がありますか?

編集:良い答えのためにpastylegsに感謝します。しかし、このようにすると、いくつかの小さなバグが発生します。誰かがこの問題に遭遇した場合、私はここで説明します。

まず、ModelClassにインポートを誤って入れてしまったので、私は循環依存性を得て、奇妙な結果を得ました。あなた自身の不満を救うために、pastylegsがしたところに置いてください。第二に、これだけで

if sender is ModelClass and instance is not Null: 
    count = ModelClass.objects.all().count() 
    stat = Stat(name='some_name', value=count).save() 

を置き換え、(新しいものを毎回作成していない)、統計の以前の計算を上書きするために:私はアプリを作成したい

if sender is ModelClass: 
    count = Match.objects.all().count() 
    try: 
     stat = Stat.objects.get(key="Total") 
     stat.update(key="Total", value=count) #Update statistic 
    except: 
     Stat(key="Total", value=count).save() #Create new 

答えて

3

は(統計と呼ばれますまたは類似の)キーと値のペアを保持するための単純なモデルがあること:

class Stat(models.Model): 
    key = models.CharField(..) 
    value = models.CharField(...) 

は、関数に、ユーザがセーブするたびに実行するために、独自のモデルに信号を使用する/モデルのインスタンスを更新します。 models.pyで:

class ModelClass(models.Model): 
    ... 

from django.db.models.signals import post_save 
from myapp.signal import updates_stats 
post_save.connect(updates_stats, sender=ModelClass) 

、その後、あなたがsignals.pyに必要な、これまでどのような統計情報を計算するために受信機機能を作成

from myapp.models import ModelClass 
from stats.models import Stat 
def update_stats(sender, instance, signal, *args, **kwargs): 
    if sender is ModelClass and instance is not Null: 
     count = ModelClass.objects.all().count() 
     stat = Stat(name='some_name', value=count).save() 

これは非常に単純かつ基本的なアプローチであり、唯一の信号を使って計算を行う方法を概説していますが、それは良いスタートです。理想的には、サーバーがハングアップしてリクエストがタイムアウトする可能性があるため、要求/応答サイクル外でこれらの値を計算することをお勧めします(特に大きなメッセージの場合)。したがって、Celeryなどのキューイング/タスクシステムを使用して実行することを検討する必要がありますバックグラウンドでの計算

+0

素晴らしい答え!これは非常に良いやり方で、まさに私が探していたものです。ありがとう@pastylegs。 – grenadejumper

関連する問題