我正在寻找一个解决方案,能够根据相关的模型实例自动更新模型实例。在
看起来很简单,我到处都找过。我不熟悉这个问题,所以让我知道我问的问题不正确,或者思考问题的方式不对。在
我需要每月捐款帐户自动更新到过去30天内所有相关捐赠的总额。同样地,年度捐赠和终身捐赠也是如此。在
我也需要帐户已订阅如果要切换为真
如果不符合要求,则返回False。在
class Account(models.Model):
...
is_subscribed = models.BooleanField(
default=False
)
monthly_donations = models.PositiveIntegerField(
default=0
)
yearly_donations = models.PositiveIntegerField(
default=0
)
lifetime_donations = models.PositiveIntegerField(
default=0
)
class Donation(models.Model):
related_account = models.ForeignKey(
Account,
on_delete=models.CASCADE,
related_name='donation'
)
amount = models.IntegerField()
date = models.DateField()
信号是解决办法吗?不过,我不希望总数只在新捐款被保存时才更新。我需要根据捐赠日期每天更新。在
信号不能百分之百地解决你的问题。因为}依赖于当前日期来给出正确的答案。在
monthly_donations
和{当代码的多个部分对同一事件感兴趣时,信号通常是一个很好的解决方案(在您的例子中,只有}这样的内置模型,您无法对其进行修改)。在
Account
实例对新的Donation
对象感兴趣)。另外,当您不能直接访问代码时(例如,第三方应用程序,或者像User
或{在您的例子中,您可以访问
Donation
模型,因此您可以重写save()
方法:但是,正如您已经提到的,您不希望仅在创建新的捐赠时才更新此信息。在
实际上,您当前存储在
Account
模型中的所有信息都可以动态计算。使用更高级的QuerySet表达式,我们可以直接在数据库中完成所有工作。即使我们每次都要计算它,它也可以很快。特别是如果你缓存结果。在这种查询称为aggregation。我将使用
annotate()
函数为您的用例写一个例子。annotate()
函数是一个特殊的函数,它根据我们定义的标准为结果集的每个实例“添加额外的字段”。在通常,我们用
annotate()
添加的字段是某事物的和,或者计数,或者平均值。在您的例子中,我们可以列出所有Account
对象,并且对于每个对象,我们可以用每月捐赠、每年捐赠和所有时间捐赠的总和来注释。我们甚至可以使用case/when查询来使用这个计算字段来检查帐户是否是订户。在它比我们一直使用的诸如
filter()
,all()
之类的琐碎的查询集要复杂一点,但是我花时间把它写下来,并给出一些可能对您有帮助的注释。在实施:
^{pr2}$用法:
这将是一个最佳解决方案。这样可以确保数据始终是最新的。另一个解决方案是像您一样保留数据库字段,并在服务器上创建一些cron jobs,这样它们就可以每天更新您的所有帐户,
Account
字段将作为计算字段的“缓存”。在{cron>然后可以用cdcron>中提到的方法组合起来。在
相关问题 更多 >
编程相关推荐