Django подсчет и хранение значений в моделях

У меня есть несколько моделей, которые выглядят следующим образом

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)

он немного больше, в любом случае, я хочу, чтобы A и B и т.д. суммировались вместе и сохраняли результат в виде суммы 1 и т.д. Сначала я подумал, что для этого подойдет форма, но поля суммы всегда должны иметь сумму, они никогда не должны обновляться, поэтому я подумал переписать метод сохранения в модели, я получил это, но это просто дает мне ошибку рекурсии, я знаю почему, но у меня нет решения для этого

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()

есть идеи?

Вы можете сделать вызов super().save(*args, **kwargs) после обновления сумм, так:

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)

Но это оченьплохая идея хранить агрегаты: это вводит форму дублирования данных, и приведет к многим проблемам с синхронизацией значений друг с другом: если вы позже измените, например, B1, вам нужно будет обновить и Sum_of_1. Хотя это может выглядеть просто, существует несколько способов через ORM, или через необработанные запросы к базе данных, или через другие приложения, которые будут обходить вызов .save(), и, таким образом, в конечном итоге данные перестанут синхронизироваться правильно. Возможно, будет лучше просто определить свойство, например:

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
Вернуться на верх