我已经使用这个 Django 代码段有一段时间了,但后来意识到它在保存数据库之前转换为整数时会引入浮点工件.此外,从 Django 1.9 SubfieldBase 已被弃用,我们应该使用 Field.from_db_value 代替.所以我编辑了代码来解决这两个问题.class CurrencyField(models.IntegerField):description = "一个在数据库中将美元保存为便士 (int) 的字段,但表现得像一个浮点数"def get_db_prep_value(self, value, *args, **kwargs):如果值为无:返回无返回 int(round(value * 100))def to_python(self, value):如果值为 None 或 isinstance(value, float):返回值尝试:返回浮点数(值)/100除了(类型错误,值错误):raise ValidationError("这个值必须是一个整数或者一个字符串代表一个整数.")def from_db_value(self, value, expression, connection, context):返回 self.to_python(value)def formfield(self, **kwargs):从 django.forms 导入 FloatField默认值 = {'form_class': FloatField}defaults.update(kwargs)返回 super(CurrencyField, self).formfield(**defaults)I am trying to create a custom field in Django which will take a decimal currency value (example: £1.56) and save it in the database as an Integer (example: 156) to store currency values.This is what I have so far (I have put fixed values to test)class CurrencyField(models.DecimalField): __metaclass__ = models.SubfieldBase def get_internal_type(self): return 'PositiveIntegerField' def to_python(self, value): print "CurrentField to_python" return Decimal(value)/100 def get_db_prep_value(self, value, connection, prepared=False): print "CurrentField get_db_prep_value" if value is None: return value print type(value) return int(value*100)I am following the Python 1.7 documentation for creating custom model fields.In the above code, the get_db_prep_value method is never being called when I save the model using this field. The to_python method is working fine (if I manually enter the value in the DB it will return the correct decimal), however it will never save the correct value.I have also tried using get_prep_value and this has the same result.How can I make it save the correct value? 解决方案 Integer based MoneyFieldI've been using this Django snippet for some time, but realized later it was introducing floating-point artifacts when converting to an integer before saving the the database.Also, as of Django 1.9 SubfieldBase has been deprecated and we should use Field.from_db_value instead. So I've edited the code to fix both of these issues.class CurrencyField(models.IntegerField): description = "A field to save dollars as pennies (int) in db, but act like a float" def get_db_prep_value(self, value, *args, **kwargs): if value is None: return None return int(round(value * 100)) def to_python(self, value): if value is None or isinstance(value, float): return value try: return float(value) / 100 except (TypeError, ValueError): raise ValidationError("This value must be an integer or a string represents an integer.") def from_db_value(self, value, expression, connection, context): return self.to_python(value) def formfield(self, **kwargs): from django.forms import FloatField defaults = {'form_class': FloatField} defaults.update(kwargs) return super(CurrencyField, self).formfield(**defaults) 这篇关于Django 创建自定义模型字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-22 18:44
查看更多