I have a Django model with a decimal field:
class User(models.Model):
...
balance = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
...
I have my app running on my development machine (Python 2.7.1, Mac OSX, Django 1.4, MySQL InnoDB), and on a production server (Python 2.6.5, Ubuntu, Django 1.4, MySQL ISAM)
The problem is on my development machine. This code works without throwing an error:
>>> u = User.objects.get(pk=1)
>>> u.balance
Decimal('9.00')
>>> u.balance=1.44
>>> u.save()
>>> u.balance
1.44
As far as I understand, u.save() should through the following error, which it does on my production instance:
>>> 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
So why is my development instance not throwing this error? Problem came up because I checked in some buggy code that passed my unit tests. This error should have been thrown. I put my environment details because it has to be due to one of those differences. I suspect MySQL ISAM vs. InnoDB, but not at all sure.
Thanks!
Your dev environment running Python 2.7 should not throw that error, but your production environment running Python 2.6 should.
From the Python docs on Decimal objects: