Opened 17 years ago
Closed 17 years ago
#8050 closed (fixed)
DecimalField no longer takes float values
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Keywords: | ||
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
As of r8143, given a model like this:
class Dec(models.Model):
avg = models.DecimalField(decimal_places=2, max_digits=5)
I'm seeing failures like this:
>>> d1 = Dec(avg=2.3)
>>> d1.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "d:\u\kmt\django\trunk\django\db\models\base.py", line 274, in save
self.save_base()
File "d:\u\kmt\django\trunk\django\db\models\base.py", line 330, in save_base
values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)]
File "d:\u\kmt\django\trunk\django\db\models\fields\__init__.py", line 232, in get_db_prep_save
return self.get_db_prep_value(value)
File "d:\u\kmt\django\trunk\django\db\models\fields\__init__.py", line 735, in get_db_prep_value
return connection.ops.value_to_db_decimal(self.to_python(value),
File "d:\u\kmt\django\trunk\django\db\models\fields\__init__.py", line 709, in to_python
return decimal.Decimal(value)
File "d:\bin\Python2.5.1\lib\decimal.py", line 578, in __new__
"First convert the float to a string")
TypeError: Cannot convert float to Decimal. First convert the float to a string
>>>
Prior to r8143 code like this worked fine. Now I realize it's called DecimalField, so perhaps I should be passing in a Decimal not a float, but when originally written this code (not the above but the code where I actually hit the problem) used a FloatField, and at some point I migrated it to DecimalField via these instructions:
http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges#RenamedFloatFieldtoDecimalField
which don't mention anywhere the need to migrate to passing in Decimals for the values. Is the intent to no longer allow passing floats here? If so it probably needs a mention in Backwards Incompatible Changes.
Change History (2)
comment:1 by , 17 years ago
| Component: | Database wrapper → Documentation |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
I think you're right on all counts (except where you try to pass a float off as a decimal). The current code is better and actually catches this as a bug. And, yes, we need to add it to BackwardsIncompatibleChanges. I'll do that momentarily.
We shouldn't really try to fake the float -> decimal conversion because it really does lose precision (and would be inconsistent with how Python works). You can pass in strings or decimals there.