[英]Django - Model property methods vs signals for field calculation
I have a model that does some basic aggregation of some values on a m2m field.我有一个模型可以对 m2m 字段上的某些值进行一些基本聚合。 I can achieve this by doing the calculation in a Model method, in which case the results would be stored in a model attribute.
我可以通过在模型方法中进行计算来实现这一点,在这种情况下,结果将存储在模型属性中。
Or I can do the calculation in a pre_save signal function, and then the result would be stored in a model field.或者我可以在 pre_save 信号函数中进行计算,然后将结果存储在模型字段中。
I want to know are there are any cons to using signals?我想知道使用信号有什么缺点吗? or in which cases it would be better to use a model property method?
或者在哪些情况下使用模型属性方法会更好?
I understand that the calculations will run at different times, with the signal function running when save() is called, and the model method running automatically.我知道计算将在不同的时间运行,调用 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)
The signal approach has the benefit of resulting in a model field rather than a model attribute, which makes it easier use in Parent or related models for aggregation.信号方法的好处是产生模型字段而不是模型属性,这使得它更容易在父模型或相关模型中用于聚合。 So why would one ever use a Model method over a model signal?
那么为什么要在模型信号上使用模型方法呢?
The difference is that the @property
will be calculated every time you access it, and the signal one will be calculated once and then stored, if you're not using the right indices they can have a big difference in performance不同之处在于每次访问时都会计算
@property
,并且将计算一次信号然后存储,如果您没有使用正确的索引,它们可能会对性能产生很大的影响
Another difference is that if you use CartItem.objects.update
, signals won't run, so you would end up with invalid data, same thing if you updated the object outside of Django directly through SQL.另一个区别是,如果您使用
CartItem.objects.update
,信号将不会运行,因此您最终会得到无效数据,如果您直接通过 SQL 在 Django 之外更新对象,则同样如此。
I'm VERY new to django, but I was asking a similar question.我对 Django 很陌生,但我问了一个类似的问题。 I had 2 time fields and needed the difference between them.
我有 2 个时间字段,需要它们之间的差异。 My first try was with a property which worked reasonably well until I realized I needed to be able to easily get a total of that difference across a queryset.
我的第一次尝试是使用一个运行良好的属性,直到我意识到我需要能够轻松地获得整个查询集的总差异。
I ended up implementing a pre_save signal to set the value of the field.我最终实现了一个 pre_save 信号来设置字段的值。 In my use case, the data doesn't change frequently, so it made sense.
在我的用例中,数据不会经常更改,所以这是有道理的。 Then I created a property on the queryset to aggregate a sum.
然后我在查询集上创建了一个属性来聚合总和。 This way I can filter first and get a sum across the subset.
这样我就可以先过滤并得到子集的总和。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.