为什么Django DecimalField让我存储Float或string?

2024-03-29 14:16:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我不明白Django DecimalField的行为。在

它的定义是:

A fixed-precision decimal number, represented in Python by a Decimal instance.

但是,对于以下型号:

class Article(models.Model)
    unit_price = DecimalField(max_digits=9, decimal_places=2)

我至少可以用三种方式创作一篇文章:

^{pr2}$

为什么Django DecimalField能够返回Decimal类型之外的其他值?在

什么是确保我的应用程序永远不会处理浮动价格的最佳方法?在

谢谢。在


Tags: djangoinstanceinnumberby定义articleclass
2条回答

好吧,decimal.Decimal子类型本身就是float,这就是为什么它在模型中被接受的原因。这个十进制。十进制类型为浮点类型提供进一步的算术精度。在

如十进制类型docs中所述,操作:

0.1 + 0.1 + 0.1 - 0.3

使用十进制。十进制精确地给出0,就像float类型给出一个接近于零的数字:

^{pr2}$

最后,decimal.Decimal数字可以准确地表示。在

A decimal number is immutable. It has a sign, coefficient digits, and an exponent. To preserve significance, the coefficient digits do not truncate trailing zeros. Decimals also include special values such as Infinity, -Infinity, and NaN. The standard also differentiates -0 from +0.

为了在应用程序中有显式的小数,还必须显式并注意十进制转换、每个db In/out或使用cast to decimal.Decimal的序列化操作。在

要进一步深入了解浮点运算在后台的作用,可以访问这个Decimal Arithmetic Specification

Why Django DecimalField is able to return something else than Decimal type?

这是因为Django在模型创建过程中是允许的,并且允许您在这些字段中输入任何类型,如果您输入的内容可以强制为指定的类型,则不会出现错误。在

在将其插入数据库后,它将获得正确的类型。您可以使用refresh_from_db()来验证:

article = Article.objects.create(unit_price="2.3")
type(article.unit_price)
>>> str
article.refresh_from_db()
type(article.unit_price)
>>> decimal.Decimal

What would be the best way to ensure my app never deals with floats for prices?

确保这一点的唯一方法是在知道价格金额后立即将任何价格输入强制到decimal.Decimal。在

相关问题 更多 >