Если значение действительно 50
против 50.0
?Объект Decimal
поддерживает то, что было изначально введено, например, Decimal('50')
yields 50
.
>>> from decimal import Decimal
>>> d = Decimal('50')
>>> print d
50
К сожалению, аргументы, предоставленные конструктору DecimalField
, предназначены только для ограничений на хранение значения, а не их отображение.
Теперь, поскольку Django просто использует стандартную библиотеку json / simplejson, вы можете указать собственный кодировщик при сериализации, например, предложенный в этот вопрос :
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)
Но это не заканчивается.Как подробно описано в этом сообщении в блоге , 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 , чтобы убедиться, что поле 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!']}