如何在 Django 中创建带小数的数学运算 - [<class 'decimal.InvalidOperation'>]
How to create mathematics operations with decimal in Django - [<class 'decimal.InvalidOperation'>]
一个非常简单的保存方法导致了这个错误:
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 这样的小数字时它会正常工作。
因为你设置的限制。 max_digits=4
和 decimal_places=2
允许保存的最大数目为 99.99(小数位包含在最大位数中)。
查看用法示例 here。
由于这些都是必需的参数,因此您可以设置足够高的值以适用于大多数用例。例如,以小数点后 10 位的分辨率存储最多约 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。
一个非常简单的保存方法导致了这个错误:
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 这样的小数字时它会正常工作。
因为你设置的限制。 max_digits=4
和 decimal_places=2
允许保存的最大数目为 99.99(小数位包含在最大位数中)。
查看用法示例 here。
由于这些都是必需的参数,因此您可以设置足够高的值以适用于大多数用例。例如,以小数点后 10 位的分辨率存储最多约 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。