I have multiple Models which look like this
class Classes(models.Model):
User = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
A1 = models.IntegerField(default=0)
B1 = models.IntegerField(default=0)
etc
A2 = models.IntegerField(default=0)
B2 = models.IntegerField(default=0)
etc
A3 = models.IntegerField(default=0)
B3 = models.IntegerField(default=0)
etc
A4 = models.IntegerField(default=0)
B4 = models.IntegerField(default=0)
etc
Sum_of_1 = models.IntegerField( blank=True, null=True)
Sum_of__2 = models.IntegerField( blank=True, null=True)
Sum_of__3 = models.IntegerField( blank=True, null=True)
Sum_of__4 = models.IntegerField( blank=True, null=True)
its a bit bigger, anyways, I want A and B etc sum together and save the result in sum of 1 etc. First I thought that a form would be good for that but the sum fields should always have the sum they never should be updated so then I thought rewriting the save method in models, I got this but it just gives me an recursion error I know why but have no solution for that
super().save(*args, **kwargs)
if self.Sum_of__1 or self.Sum_of__2 or self.Sum_of__3 or self.Sum_of__4 is None:
self.Sum_of__1 = self.A1 self.B1 self.C1 self.D1 self.E1
self.Sum_of__2 = self.A2 self.B2 self.C2 self.D2 self.E2
self.Sum_of__3 = self.A3 self.B3 self.C3 self.D3 self.E3
self.Sum_of__4 = self.A4 self.B4 self.C4 self.D4 self.E4
self.save()
any ideas ?
CodePudding user response:
You can make a call to the super().save(*args, **kwargs)
after updating the sums, so:
def save(self, *args, **kwargs):
if self.Sum_of_1 is None or self.Sum_of_2 is None or self.Sum_of_3 is None or self.Sum_of_4 is None:
self.Sum_of_1 = self.A1 self.B1 self.C1 self.D1 self.E1
self.Sum_of_2 = self.A2 self.B2 self.C2 self.D2 self.E2
self.Sum_of_3 = self.A3 self.B3 self.C3 self.D3 self.E3
self.Sum_of_4 = self.A4 self.B4 self.C4 self.D4 self.E4
super().save(*args, **kwargs)
But it is a really bad idea to store aggregates: it introduces a form of data duplication, and will result in a lot of trouble to keep the values in sync with each other: if you later change for example B1
, you will need to updater Sum_of_1
as well. While that may look easy, there are several ways through the ORM, or through raw database queries, or other applications, that will circumvent the .save()
call, and thus eventually the data will no longer be synced correctly. It might be better to just define a property, like:
from django.conf import settings
class MyModel(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MDOEL,
on_delete=models.SET_NULL,
null=True
)
A1 = models.IntegerField(default=0)
B1 = models.IntegerField(default=0)
# etc.
A2 = models.IntegerField(default=0)
B2 = models.IntegerField(default=0)
# etc.
A3 = models.IntegerField(default=0)
B3 = models.IntegerField(default=0)
# etc.
A4 = models.IntegerField(default=0)
B4 = models.IntegerField(default=0)
# etc.
@property
def sum_of_1(self):
return self.A1 self.B1 self.C1 self.D1 self.E1
@property
def sum_of_1(self):
return self.A1 self.B1 self.C1 self.D1 self.E1
@property
def sum_of_2(self):
return self.A2 self.B2 self.C2 self.D2 self.E2
@property
def sum_of_3(self):
return self.A3 self.B3 self.C3 self.D3 self.E3
@property
def sum_of_4(self):
return self.A4 self.B4 self.C4 self.D4 self.E4