Как создавать математические операции с десятичной дробью в Django - [ ] - PullRequest
0 голосов
/ 16 марта 2020

Очень простой метод сохранения вызывает эту ошибку:

class Shift(models.Model):
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE)
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(null=True)
    closing_type_amount = models.DecimalField(max_digits=4, decimal_places=2, default=0)
    closing_actual_amount = models.DecimalField(max_digits=4, decimal_places=2, default=0)
    diff = models.DecimalField(max_digits=4, decimal_places=2, null=True)
    on_duty = models.BooleanField(default=True)

    def save(self, *args, **kwargs):
        self.diff = float(self.closing_type_amount) - float(self.closing_actual_amount)
        super(Shift, self).save(*args, **kwargs)

Причиной этой ошибки является строка self.diff = float(self.closing_type_amount) - float(self.closing_actual_amount) ПРИМЕЧАНИЕ , когда дают входные данные больше 100, она терпит неудачу, когда А маленькие цифры вроде 5, 4, 6, 11 работают нормально.

1 Ответ

1 голос
/ 16 марта 2020

Из-за установленных вами ограничений. max_digits=4 и decimal_places=2 позволяет сохранить максимальное число 99,99 (десятичные разряды включены в максимальные цифры).

См. Пример использования здесь .

Поскольку оба являются обязательными аргументами, вы можете установить что-то достаточно высокое, чтобы работать в большинстве случаев. Например, для хранения чисел примерно до одного миллиарда с разрешением 10 десятичных знаков:

models.DecimalField(..., max_digits=19, decimal_places=10)

Я бы также предложил немного изменить вашу модель, потому что, на мой взгляд, сохранение значения diff избыточно, так как у вас уже есть два значения, из которых вы рассчитываете. Скорее добавьте свойство к вашей модели, чтобы вычислить его на лету:

class Shift(models.Model):
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE)
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(null=True)
    closing_type_amount = models.DecimalField(max_digits=4, decimal_places=2, default=0)
    closing_actual_amount = models.DecimalField(max_digits=4, decimal_places=2, default=0)
    on_duty = models.BooleanField(default=True)

    @property
    def diff(self):
        return float(self.closing_type_amount) - float(self.closing_actual_amount)

Кроме того, если вы собираетесь привести к float, вы также можете использовать FloatField вместо DecimalField .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...