我想提供关于班级实例的一般统计数据" ModelClass"在我的用户的网页上。可以说有几千个ModelClass对象,我需要计算很多统计数据。我已经发现我可以用模型管理器做到这一点,这是一个(非常)简化的例子:
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() - 方法来完成。
保存这些结果的最佳方法是什么?我应该创建另一个用于保存计算统计数据的django模型,还是存在另一种存储此信息的方法?
编辑:感谢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
答案 0 :(得分:4)
我创建了一个名为statistics(或类似)的应用程序,它有一个简单的模型来保存键值对:
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这样的排队/任务系统来执行在后台计算