尾随零在我的DecimalField上显示不一致

时间:2014-05-02 20:13:44

标签: python django

我想使用带有6位小数的DecimalField并在独立模型中测试它:

class MyItem(models.Model):
    myval = models.DecimalField(max_digits=18, decimal_places=6)
    def __str__(self):
        return str(self.myval)

现在我正在使用内置管理员,并观察以下内容:

  • 添加最多4位小数的值按预期工作(0.0001)
  • 添加大于1的值似乎没问题

但是,添加0.000010.000001等值会显示尾随零,即0.000010

虽然它在数学上是正确的(相同的数字),并且我可以用很少的工作来修剪零,但我很困扰有时这个零出现,有时候,它没有。我还没有测试过很多种数字,并且不确定是否真的会为所有数字保存正确的数值。

据我了解,DecimalField应该保持准确性。我是否遗漏了创建模型的基本内容?发生了什么事?

使用的版本是Python 3.3和Django 1.6

1 个答案:

答案 0 :(得分:1)

这里是一个应该解决问题的DecimalField模型的覆盖,找到了here

class NonscientificDecimalField(DecimalField):
    """ Prevents values from being displayed with E notation, with trailing 0's
        after the decimal place  truncated. (This causes precision to be lost in
        many cases, but is more user friendly and consistent for non-scientist
        users)
    """
    def value_from_object(self, obj):
        def remove_exponent(val):
            """Remove exponent and trailing zeros.
               >>> remove_exponent(Decimal('5E+3'))
               Decimal('5000')
            """
            context = decimal.Context(prec=self.max_digits)
            return val.quantize(decimal.Decimal(1), context=context) if val == val.to_integral() else val.normalize(context)

        val = super(NonscientificDecimalField, self).value_from_object(obj)
        if isinstance(val, decimal.Decimal):
            return remove_exponent(val)