oro*_*aki 63 python django currency decimal django-models
我在这里遇到了范式问题.我不知道是否应该将钱存储为Decimal(),或者我是否应该将其存储为字符串并将其自身转换为小数.我的理由是这样的:
PayPal需要2个小数位,所以如果我有一个49美元的产品,PayPal希望看到49.00遇到问题.Django的DecimalField()不设置小数.它只存储最大小数位数.所以,如果你有49个,并且你将字段设置为2个小数位,它仍然将它存储为49.我知道Django基本上是类型转换,当它从数据库反序列化为Decimal时(因为数据库)没有十进制字段),所以我并不完全关心速度问题,就像我遇到这个问题的设计问题一样.我想做可扩展性最好的事情.
或者,更好的是,是否有人知道如何配置django DecimalField()以始终使用TWO_PLACES格式样式进行格式化.
Wil*_*rdy 62
您可能想要使用该.quantize()方法.这会将十进制值四舍五入到一定数量的位置,您提供的参数指定位数:
>>> from decimal import Decimal
>>> Decimal("12.234").quantize(Decimal("0.00"))
Decimal("12.23")
Run Code Online (Sandbox Code Playgroud)
它还可以通过参数来指定您想要的舍入方法(不同的会计系统可能需要不同的舍入).Python文档中的更多信息.
以下是自动生成正确值的自定义字段.请注意,这仅在从数据库中检索时,并且在您自己设置时不会帮助您(直到您将其保存到数据库并再次检索它!).
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
Run Code Online (Sandbox Code Playgroud)
[编辑]
添加__metaclass__,请参阅Django:为什么此自定义模型字段的行为不符合预期?
Val*_*lev 18
我想你应该将其存储在十进制格式,并格式化,以00.00格式只后发送给贝宝,就像这样:
pricestr = "%01.2f" % price
Run Code Online (Sandbox Code Playgroud)
如果需要,可以向模型添加方法:
def formattedprice(self):
return "%01.2f" % self.price
Run Code Online (Sandbox Code Playgroud)
so_*_*so_ 13
我迟到的派对版本增加了南迁移.
from decimal import Decimal
from django.db import models
try:
from south.modelsinspector import add_introspection_rules
except ImportError:
SOUTH = False
else:
SOUTH = True
class CurrencyField(models.DecimalField):
__metaclass__ = models.SubfieldBase
def __init__(self, verbose_name=None, name=None, **kwargs):
decimal_places = kwargs.pop('decimal_places', 2)
max_digits = kwargs.pop('max_digits', 10)
super(CurrencyField, self). __init__(
verbose_name=verbose_name, name=name, max_digits=max_digits,
decimal_places=decimal_places, **kwargs)
def to_python(self, value):
try:
return super(CurrencyField, self).to_python(value).quantize(Decimal("0.01"))
except AttributeError:
return None
if SOUTH:
add_introspection_rules([
(
[CurrencyField],
[],
{
"decimal_places": ["decimal_places", { "default": "2" }],
"max_digits": ["max_digits", { "default": "10" }],
},
),
], ['^application\.fields\.CurrencyField'])
Run Code Online (Sandbox Code Playgroud)
ais*_*baa 12
钱应存放在货币领域,遗憾的是不存在.由于货币是二维价值(金额,货币).
有python-money lib,有很多分叉,但我找不到工作.
建议:
python-money可能是最好的叉子https://bitbucket.org/acoobe/python-money
akumria推荐的django-money:http://pypi.python.org/pypi/django-money/ (尚未尝试过那个).
Aar*_*lla 10
我建议避免将表示与存储混合.将数据存储为具有2个位置的十进制值.
在UI层中,以适合用户的形式显示它(因此可能省略".00").
将数据发送到PayPal时,请按接口要求对其进行格式化.