如果实际值为50
与50.0
? A Decimal
对象维持最初输入的内容,例如Decimal('50')
收益率50
。
>>> from decimal import Decimal
>>> d = Decimal('50')
>>> print d
50
不幸的是提供给DecimalField
构造函数的参数是仅适用于限制存储值,而不是显示它们。
现在,因为Django是仅仅使用标准的JSON/simplejson lib中,你可以序列化的时候,比如在this question建议指定自定义编码器:
import decimal
import json
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, decimal.Decimal):
return '%.2f' % obj # Display Decimal obj as float
return json.JSONEncoder.default(self, obj)
但它并没有结束。作为detailed in this blog post,Django是明确地传递cls=DjangoJSONEncoder
到simplejson.dump(...)
,所以我们也通过创建一个自定义序列化对象的引用来规避这个DecimalEncoder
我们创建:
from django.core.serializers.json import Serializer as JSONSerializer
class DecimalSerializer(JSONSerializer):
def end_serialization(self):
self.options.pop('stream', None)
self.options.pop('fields', None)
json.dump(self.objects, self.stream, cls=DecimalEncoder, **self.options)
接下来,实例化DecimalSerializer
作为自己的序列化对象,魔术发生:
my_serializer = DecimalSerializer()
print my_serializer.serialize([obj], indent=4)
其中产量:
[
{
"pk": 1,
"model": "app.foomodel",
"fields": {
"foo": "50.00"
}
}
]
这看起来很多工作。在保存之前,使用Django的model validation来确保FooModel.foo
字段总是浮点数,可能会更容易。这里是蛮力试图在此:
from django.core.exceptions import ValidationError
class FooModel(models.Model):
foo = models.DecimalField(max_digits=6, decimal_places=3, null=True)
def clean(self):
if '.' not in str(self.foo):
raise ValidationError('Input must be float!')
def save(self, *args, **kwargs):
self.full_clean()
super(FooModel, self).save(*args, **kwargs)
然后:
>>> f = FooModel(foo='1')
>>> f.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/jathan/sandbox/foo/app/models.py", line 15, in save
self.full_clean()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 828, in full_clean
raise ValidationError(errors)
ValidationError: {'__all__': [u'Input must be float!']}
这种串行仍呈现在JSON字符串。 是否有理由不将“.2f'%obj”替换为“float('。2f'%obj)”? –
这太复杂了 - 最好不要在第一时间使用Django的DecimalField。 – jononomo
你可能是对的,但请记住这是在Django 1.3的日子里3.5年前发布的。请随时帮我更新它。 :) – jathanism