Django:我应该如何存储货币价值? - python

我在这里遇到范式问题。我不知道该将钱存储为Decimal(),还是将其存储为字符串并将自己转换为十进制。我的推理是这样的:

PayPal要求小数点后两位为,因此,如果我有49美元的产品,PayPal希望看到49.00。 Django的DecimalField()并未设置小数位数。它仅存储最大小数位数。因此,如果其中有49个字段,并且将字段设置为2个小数位,它仍将其存储为49个。我知道Django从数据库反序列化为Decimal时基本上就是类型转换(因为Databases (没有小数字段),因此我对速度问题的关注程度与对这个问题的设计问题的关注程度一样。我想做最好的可扩展性。

或者,更好的是,没有人知道如何将django DecimalField()配置为始终使用TWO_PLACES格式化样式进行格式化。

参考方案

您可能要使用.quantize()方法。这会将十进制值四舍五入到一定位数,您提供的参数指定位数:

>>> from decimal import Decimal
>>> Decimal("12.234").quantize(Decimal("0.00"))
Decimal("12.23")

它还可以使用一个参数来指定所需的舍入方法(不同的会计系统可能需要不同的舍入)。在Python docs中有更多信息。

下面是一个自定义字段,它会自动产生正确的值。请注意,这仅是从数据库中检索到的,并且在您自行设置时不会帮助您(直到将其保存到数据库并再次检索!)。

from django.db import models
from decimal import Decimal
class CurrencyField(models.DecimalField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        try:
           return super(CurrencyField, self).to_python(value).quantize(Decimal("0.01"))
        except AttributeError:
           return None

[编辑]

添加了__metaclass__,请参见Django: Why does this custom model field not behave as expected?

45码