[英]django integer model field with float form input
I am working with a django model which stores currency values as integers.我正在使用将货币值存储为整数的 django 模型。 ie GBP22.35 gets stored as 2235.
即 GBP22.35 存储为 2235。
When that model gets rendered as a form, I need to be able to associate a widget with that integer field so can be edited as though it were a float value (ie to two decimal places - 22.35) and is validated as such.当该模型呈现为表单时,我需要能够将一个小部件与该整数字段相关联,以便可以像它是一个浮点值(即两位小数 - 22.35)一样进行编辑,并以此进行验证。 form.save() then needs to save the native integer value to the db.
form.save() 然后需要将本机整数值保存到数据库。
I've tried creating a custom FormField/Widget pair which involves dividing by 100 in the widgets render and multiplying back up in the fields to_python method, but it all goes awry if there is an error on the form.我尝试创建一个自定义的 FormField/Widget 对,其中涉及在小部件渲染中除以 100,并在字段 to_python 方法中乘以备份,但是如果表单上有错误,这一切都会出错。 The widget keeps re-dividing the value.
小部件不断重新划分值。
I realise this could be avoided by using float/decimal model fields but that is not an option in this case.我意识到可以通过使用浮点/十进制模型字段来避免这种情况,但在这种情况下这不是一个选项。
Is this something people have done before?这是人们以前做过的事情吗? Any pointers?
任何指针? Thanks.
谢谢。
You could implement a subclass of IntegerField
that handles that conversion behind the scenes:您可以实现一个
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)
Should behave as DecimalField
in your Django code, but as IntegerField
in your database.在你的 Django 代码中应该表现为
DecimalField
,但在你的数据库中表现为IntegerField
。
Update: simpler implementation derived from IntegerField
instead of DecimalField
;更新:从
IntegerField
而不是DecimalField
派生的更简单的实现; added validation as implemented in DecimalField.to_python
添加了在
DecimalField.to_python
中实现的验证
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.