Opened 4 years ago

Closed 3 years ago

#32559 closed New feature (fixed)

Add attribute 'step' to FloatField.

Reported by: Jacob Rief Owned by: Jacob Rief
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 Jacob Rief)

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.

Patch: https://github.com/django/django/pull/14162

Change History (24)

comment:1 by Markus Holtermann, 4 years ago

Triage Stage: UnreviewedAccepted

Thank you. Sounds like a perfectly valid use case.

comment:3 by Kapil Bansal, 4 years ago

Owner: changed from nobody to Kapil Bansal
Status: newassigned

comment:4 by Kapil Bansal, 4 years ago

Description: modified (diff)
Has patch: set
Last edited 4 years ago by Mariusz Felisiak (previous) (diff)

comment:5 by Mariusz Felisiak, 4 years ago

Summary: Add attribute 'step' to FloatField and DecimalFieldAdd attribute 'step' to FloatField.

comment:6 by Mariusz Felisiak, 4 years ago

Description: modified (diff)

comment:7 by Mariusz Felisiak, 4 years ago

Needs tests: set

comment:8 by Kapil Bansal, 4 years ago

Description: modified (diff)
Needs tests: unset

comment:9 by Adam Johnson, 3 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 Kapil Bansal, 3 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 Jacob Rief, 3 years ago

Description: modified (diff)

comment:12 by Jacob Rief, 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.

comment:13 by Jacob Rief, 3 years ago

Owner: changed from Kapil Bansal to Jacob Rief

Reclaiming ticket because of missing progress.

A new pull request is here: https://github.com/django/django/pull/14532
This adds the missing documentation and release note for this feature.

comment:14 by Carlton Gibson, 3 years ago

Needs tests: set
Patch needs improvement: set

comment:15 by Carlton Gibson, 3 years ago

Current PR removes the default step="any" which is a problem.

Comment from PR:

This introduces a regression from 7ec2a21be15af5b2c7513482c3bcfdd1e12782ed.

We need a selenium test to cover it, but if I create an <input type="number" /> without the step specified at all, I can't enter a non-integer value, such as 0.5 without triggering the browser validation (Enter a valid value).

This ties in with MDN docs for step:

The default stepping value for number inputs is 1, allowing only integers to be entered…

Version 0, edited 3 years ago by Carlton Gibson (next)

comment:16 by Jacob Rief, 3 years ago

I re-added the attribute step="any" to the FloatField . However, I don't know where to add a Selenium test for check this.

comment:17 by Carlton Gibson, 3 years ago

Needs tests: unset
Patch needs improvement: unset

Thanks Jacob! I'll take another look.

comment:18 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

In 4b8e9492:

Refs #32559 -- Added selenium test for FloatField client-side validation.

step="any" is required for non-integer values. See:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#step

Covers behaviour added in 7ec2a21be15af5b2c7513482c3bcfdd1e12782ed.

comment:19 by Carlton Gibson, 3 years ago

Patch needs improvement: set

comment:20 by Jacob Rief, 3 years ago

step="any" is required for non-integer values.

shall I add this? According to the Mozilla developer docs, the step is not mandatory and default to 1 for number input fields, so I'm unsure what to change here.

comment:21 by Carlton Gibson, 3 years ago

Hey Jacob. See my comment on the PR for outstanding issues. Specifically, the docs need versionchanged/versionadded annotations, and (more) the new validator needs tests, matching those for the other validator classes.

comment:22 by Jacob Rief, 3 years ago

  • Added versionadded annotations to the docs.
  • Added tests for new validator StepValueValidator.
  • Fixed all annotations from black and flake8.

comment:23 by Carlton Gibson, 3 years ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:24 by Carlton Gibson <carlton@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In 3a82b5f6:

Fixed #32559 -- Added 'step_size’ to numeric form fields.

Co-authored-by: Jacob Rief <jacob.rief@…>

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