Opened 16 years ago

Closed 16 years ago

#8050 closed (fixed)

DecimalField no longer takes float values

Reported by: Karen Tracey <kmtracey@…> 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 Malcolm Tredinnick, 16 years ago

Component: Database wrapperDocumentation
Triage Stage: UnreviewedAccepted

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.

comment:2 by Malcolm Tredinnick, 16 years ago

Resolution: fixed
Status: newclosed

Done. Thanks, Karen.

Note: See TracTickets for help on using tickets.
Back to Top