使用浮点输入的Django整数字段
我正在使用一个Django模型,这个模型把货币值存储为整数。比如,GBP22.35会被存储为2235。
当这个模型以表单的形式展示出来时,我需要把这个整数字段和一个控件关联起来,这样就可以像处理浮点数一样编辑它(也就是保留两位小数,比如22.35),并且要对这个值进行验证。然后,form.save()需要把原始的整数值保存到数据库中。
我尝试创建一个自定义的表单字段和控件组合,方法是在控件的渲染中把值除以100,而在字段的to_python方法中再乘回来,但如果表单出现错误,这个过程就会出问题。控件会不断地重新将值除以100。
我意识到如果使用浮点数或十进制的模型字段,这个问题是可以避免的,但在这种情况下,这并不是一个选项。
有人做过类似的事情吗?有什么建议吗?谢谢。
1 个回答
2
你可以创建一个 IntegerField
的子类,这样就能在后台处理转换的事情:
import decimal
from django.db import models
from django.core import exceptions
from django.utils.translation import ugettext_lazy as _
class CentsField(models.IntegerField):
empty_strings_allowed = False
default_error_messages = {
'invalid': _("'%(value)s' value must be a decimal number."),
}
description = _("Fixed-point number")
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if value is None or isinstance(value, decimal.Decimal):
return value
try:
if isinstance(value, int):
return decimal.Decimal(value) / 100
else:
return decimal.Decimal(value)
except decimal.InvalidOperation:
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
params={'value': value},
)
def get_prep_value(self, value):
return int(value * 100)
在你的 Django 代码中,它应该表现得像 DecimalField
,但在你的数据库中,它则像 IntegerField
。
更新:这个实现比起 DecimalField
更简单,是从 IntegerField
派生的;还增加了像 DecimalField.to_python
中那样的验证功能。