【问题标题】:Django: DecimalField accepting floats, but this should throw an errorDjango:DecimalField 接受浮点数,但这应该会引发错误
【发布时间】:2012-09-26 07:40:08
【问题描述】:

我有一个带十进制字段的 Django 模型:

class User(models.Model):
    ...
    balance = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    ...

我的应用程序在我的开发机器(Python 2.7.1、Mac OSX、Django 1.4、MySQL InnoDB)和生产服务器(Python 2.6.5、Ubuntu、Django 1.4、MySQL ISAM)上运行

问题出在我的开发机器上。此代码可以正常工作而不会引发错误:

>>> u = User.objects.get(pk=1)
>>> u.balance
Decimal('9.00')
>>> u.balance=1.44
>>> u.save()
>>> u.balance
1.44

据我了解,u.save() 应该通过以下错误,它在我的生产实例上发生:

>>> u.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 463, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 529, in save_base
    rows = manager.using(using).filter(pk=pk_val)._update(values)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 557, in _update
    return query.get_compiler(self.db).execute_sql(None)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 986, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 808, in execute_sql
    sql, params = self.as_sql()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 951, in as_sql
    val = field.get_db_prep_save(val, connection=self.connection)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py", line 873, in get_db_prep_save
    return connection.ops.value_to_db_decimal(self.to_python(value),
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py", line 847, in to_python
    return decimal.Decimal(value)
  File "/usr/lib/python2.6/decimal.py", line 649, in __new__
    "First convert the float to a string")
TypeError: Cannot convert float to Decimal.  First convert the float to a string

那么为什么我的开发实例没有抛出这个错误呢?出现问题是因为我签入了一些通过单元测试的错误代码。这个错误应该被抛出。我放了我的环境细节,因为它必须是由于这些差异之一。我怀疑 MySQL ISAM 与 InnoDB,但完全不确定。

谢谢!

【问题讨论】:

    标签: django decimal


    【解决方案1】:

    运行 Python 2.7 的开发环境不应该抛出该错误,但运行 Python 2.6 的生产环境应该。

    来自Decimal objects 上的 Python 文档:

    在 2.7 版更改:现在允许构造函数的参数是浮点实例。

    【讨论】:

    • 教训,一如既往,是RTFM(密切)。谢谢!
    • 我也在 Python 2.7 中开发并在 2.6 中部署。我不止一次被这种行为所吸引;)
    • 另一课是尽你所能让你的开发环境和你的生产环境一样。
    猜你喜欢
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多