【问题标题】:Django - Model property methods vs signals for field calculationDjango - 用于字段计算的模型属性方法与信号
【发布时间】:2020-01-05 10:55:06
【问题描述】:

我有一个模型,它对 m2m 字段上的一些值进行一些基本聚合。我可以通过在 Model 方法中进行计算来实现这一点,在这种情况下,结果将存储在模型属性中。

或者我可以在 pre_save 信号函数中进行计算,然后将结果存储在模型字段中。

我想知道使用信号有什么缺点吗?或者在哪些情况下使用模型属性方法会更好?

我知道计算会在不同的时间运行,调用 save() 时会运行信号函数,而模型方法会自动运行。

class CartItem(models.Model):
    name = models.CharField(max_length=100)
    total_price = models.DecimalField(max_digits=10, decimal_places=2)

##Model Method Approach
    @property
    def price(self):
        return self.extras.all().aggregate(Sum('price'))['price__sum']

##Signal Approach
def set_total_price(sender, instance, **kwargs):
      instance.total_price= instance.extras.all().aggregate(Sum('price'))['price__sum'] 

pre_save.connect(set_total_price, sender=CartItem)

信号方法的好处是产生一个模型字段而不是模型属性,这使得它更容易在父模型或相关模型中用于聚合。那么为什么要对模型信号使用模型方法呢?

【问题讨论】:

    标签: python django django-models django-signals


    【解决方案1】:

    我对 django 很陌生,但我问了一个类似的问题。我有 2 个时间字段,需要它们之间的差异。我的第一次尝试是使用一个运行良好的属性,直到我意识到我需要能够轻松地获得跨查询集的总差异。

    我最终实现了一个 pre_save 信号来设置字段的值。在我的用例中,数据不会经常更改,因此很有意义。然后我在查询集上创建了一个属性来聚合一个总和。这样我就可以先过滤并得到子集的总和。

    【讨论】:

      【解决方案2】:

      不同之处在于,@property 将在您每次访问时计算一次,而信号一次将计算一次然后存储,如果您没有使用正确的索引,它们的性能可能会有很大差异

      另一个区别是,如果您使用CartItem.objects.update,信号将不会运行,因此您最终会得到无效数据,如果您在 Django 外部直接通过 SQL 更新对象也是如此。

      【讨论】:

        猜你喜欢
        • 2016-10-12
        • 2021-07-30
        • 2010-11-30
        • 1970-01-01
        • 1970-01-01
        • 2014-01-07
        • 2020-07-24
        • 2020-08-06
        • 1970-01-01
        相关资源
        最近更新 更多