class A(models.Model):
def calculate(self):
# calculate some field based on all self.b_set instances
class B(models.Model):
a = models.ForeignKey(A)
I’d like saving an instance of B to cause a function to fire on A, but efficiently.
A naive implementation would be to hook up to the post_save signal emitted by B instances then run b.a.calculate(), but it would call a.calculate() N times.
Does anybody have any suggestions for how to implement this more efficiently?
I’m hitting a roadblock because I’m not sure how I would determine when the last B instance was successfully updated after which I’d want the A instance run its potentially expensive calculate() function.
My best idea so far might be a “changed” flag on A and have a cron job pick up which A models need to be updated, but I wish it could be more accurate.
If you have a formula
x = a+b+cthen you would always want to recalculate x after any of the arguments a,b or c changes. In your model above, if the calculated field value in model A depends on the relationships in model B then you would always want to recalculate after one of B instances change. However that does not necessary means the post_save will run N times. It will only run once every time one of B instances get saved.If B has many fields that don not affect the expensive A.calculate() function, then adding a temporary checksum around the B’s fields that matter to calculate and store the value as a new B field. Your post_save then can recalculate the checksum to see whether A.calculate() needs to run again or not.