【问题标题】:Django creating a custom model fieldDjango 创建自定义模型字段
【发布时间】:2015-04-16 05:47:01
【问题描述】:

我正在尝试在 Django 中创建一个自定义字段,它将采用十进制货币值(例如:1.56 英镑)并将其作为整数(例如:156)保存在数据库中以存储货币值。

这是我目前所拥有的(我已经将固定值进行测试)

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)

我正在关注Python 1.7 documentation for creating custom model fields

在上面的代码中,当我使用该字段保存模型时,永远不会调用 get_db_prep_value 方法。 to_python 方法工作正常(如果我在数据库中手动输入值,它将返回正确的小数),但它永远不会保存正确的值。

我也尝试过使用get_prep_value,结果相同。

如何让它保存正确的值?

【问题讨论】:

    标签: python django django-models django-forms django-1.7


    【解决方案1】:

    Integer based MoneyField

    我一直在使用这个 Django sn-p 一段时间,但后来意识到它在保存数据库之前转换为整数时引入了浮点工件。

    此外,从 Django 1.9 SubfieldBase has been deprecated 开始,我们应该改用 Field.from_db_value。所以我编辑了代码来解决这两个问题。

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-11
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      相关资源
      最近更新 更多