Code

Opened 6 years ago

Closed 6 years ago

#8050 closed (fixed)

DecimalField no longer takes float values

Reported by: Karen Tracey <kmtracey@…> Owned by: nobody
Component: Documentation Version: master
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

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.

Attachments (0)

Change History (2)

comment:1 Changed 6 years ago by mtredinnick

  • Component changed from Database wrapper to Documentation
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to 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.

comment:2 Changed 6 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

Done. Thanks, Karen.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.