【问题标题】:Django wont store .00 on whole number decimal fieldsDjango 不会在整数十进制字段上存储 .00
【发布时间】:2012-09-24 06:55:56
【问题描述】:

我试图强制 Django 始终存储小数点后 2 位的数字,但如果数字是整数,那么它不会存储 .00

def clean_myfield(self):
    data = self.cleaned_data['myfield']
    self.cleandecimal(data)
    return data

def cleandecimal(self, data):
    data = Decimal(data).quantize(Decimal('.01'), rounding=ROUND_DOWN)
    print 'data ', data
    return data

我的打印始终按预期显示,例如4.00 但存储为 4

如何重写 save 方法来存储值而不四舍五入?

【问题讨论】:

  • 模型中的字段是什么类型的?
  • 抱歉,它们都是标准的models.DecimalField 或派生自models.DecimalField 的自定义类型
  • 为什么将其存储为4 会出现问题?只要它不将4.10 存储为4,我就不会在这里看到问题。

标签: django model save rounding


【解决方案1】:

这是一个表示问题。十进制数存储数字,而不是它们的表示。数学上1.00 等于1。因此,您的数据库后端可能存储最小的截断十进制而不全为零 - 所以它可能不是 Django,而是 db。如果你想强制 Django 总是返回带两位小数的小数,你可以覆盖 DecimalField:

class MyDecimalField(models.DecimalField):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        places = kwargs.get('decimal_places', 2)
        self.q = Decimal(10) ** -places

    def to_python(self, value):
        value = super(self.__class__, self).to_python(value)

        if isinstance(value, Decimal):
            return value.quantize(self.q)

        else:
            return value

这将始终返回指定的带有decimal_places 的数字。你可以像平常DecimalField一样使用它,比如:

class FooModle(models.Model)
    number = MyDecimalField(decimal_places=2, max_digits=10)

【讨论】:

  • 是的,在尝试在数据库本身中输入一个值后,我认为它与数据库相关。谢谢,我现在就试试看。
【解决方案2】:

使用models.DecimalField(max_digits = 6, decimal_places = 2) 存储两位小数的数字。

【讨论】:

  • 模型字段已经有 decimal_places=2max_digits=10 所以有些东西正在四舍五入任何值为 .00
  • 那么表格中可能有问题。尝试在 clean_myfield 中打印 data。检查是否返回两位小数。
  • 没错。我总是犯愚蠢的错误。所以 clean_myfield 中的data = self.cleandecimal(data) 做得很好!但该模型仍然不存储 .00 小数。如果我直接编辑数据库中的字段,那么它也会删除 .00。这是一个更大的问题
  • 您是否尝试过在表单类之外定义 cleandecimal 函数?我尝试使用与您相同的编码。一切对我来说都很好。唯一的区别是我在表单类之外定义了 cleandecimal 函数。
  • @miki725 指出问题出在 db 而不是 Django,所以他的回答解决了我的问题。不过谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 2020-11-06
相关资源
最近更新 更多