Opened 4 years ago
Last modified 3 years ago
#32559 closed New feature
Add attribute 'step' to FloatField. — at Version 12
Reported by: | Jacob Rief | Owned by: | Kapil Bansal |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | FloatField, NumberInput, step |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
If someone wants to use the step
attribute as provided by the HTML field
<input type="number" ...>
, she/he has to specify that using for instance
FloatField(widget=NumberInput(attrs={'step': 0.5}))
.
Since the HTML standard offers a step
attribute on input fields of type="number"
,
this feature shall be reflected by Django's FloatField
and optionally DecimalField
,
rather than having to parametrize the widget.
Min- and max-values are already supported by the FloatField
, so the step-value
would make sense here as well. It furthermore would require to revalidate the
step-value by Django's Form validation, rather than by HTML alone.
Change History (12)
comment:1 by , 4 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 4 years ago
Description: | modified (diff) |
---|---|
Has patch: | set |
comment:5 by , 4 years ago
Summary: | Add attribute 'step' to FloatField and DecimalField → Add attribute 'step' to FloatField. |
---|
comment:6 by , 4 years ago
Description: | modified (diff) |
---|
comment:7 by , 4 years ago
Needs tests: | set |
---|
comment:8 by , 4 years ago
Description: | modified (diff) |
---|---|
Needs tests: | unset |
comment:9 by , 4 years ago
On the forum, Kapil wrote:
Hi,
I was working on ticket 32559 to add step in FloatField but how to write validation check for this.
Due to python floating point issues, I am not able to validate whether field value is of given step_size or not
The loss of precision in floating points is a real issue. The normal way to validate would be to use the modulo operator to check there is no remainder after dividing by the step, but this isn't possible in floating points with common decimal steps like 0.1:
>>> step = 0.1 >>> 1 % step == 0 False >>> 1 % step 0.09999999999999995
This problem cannot be solved for FloatField
- I suggest we move the ticket to modify DecimalField
, as Decimal
objects do not have the same problem:
>>> from decimal import Decimal >>> step = Decimal('0.1') >>> Decimal(1) % step == 0 True >>> Decimal(1) % step Decimal('0.0')
We'd want to enforce that step
is given as a Decimal
.
The float
problem can also occur when constructing a Decimal
from a float
:
>>> Decimal(0.1) Decimal('0.1000000000000000055511151231257827021181583404541015625')
Perhaps we should have a check that the given step does not have more than 10 digits after the decimal point?
comment:10 by , 4 years ago
Hi,
I got a reply on mailing list to use math.isclose function. Pull Request is already opened to be reviewed
comment:11 by , 3 years ago
Description: | modified (diff) |
---|
comment:12 by , 3 years ago
Description: | modified (diff) |
---|
I reviewed that pull request and after some testing I came to the conclusion, that math.isclose
with a tolerance of 1e-9
is the best solution to fix the floating point rounding errors. All other approaches did not work properly or were far too complicated.
Thank you. Sounds like a perfectly valid use case.