If decimal_places is too big(the exact value for `big` should be found
here http://www.w3.org/TR/2012/WD-html5-20121025/common-microsyntaxes.html
#rules-for-parsing-floating-point-number-values) the step value parses to
0, which is not valid (http://www.w3.org/TR/2012/WD-html5-20121025/common-
input-element-attributes.html#attr-input-step). It is not good in itself,
but it also causes surprising and unwanted behaviour.
For example in Google Chrome input with type="number" and
step="0.0000000000000000000000000000001" accepts only integer values!
A possible fix is to add optional `step` argument to DecimalField and,
and if it is not provided just use "any".
--
Ticket URL: <https://code.djangoproject.com/ticket/20765>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* severity: Normal => Release blocker
* cc: charettes (added)
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
* stage: Unreviewed => Accepted
Comment:
We shouldn't add a `step` argument to `DecimalField` since it only concern
the `widget`.
Do you know the exact value for `big`?
We could attempt defaulting `step` to the current behavior when
`decimal_place < big` and fallback to `any` just how
[https://github.com/django/django/blob/stable/1.6.x/django/forms/fields.py#L286
`FloatField`] does.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:1>
Comment (by anonymous):
>Do you know the exact value for big?
No, I'm not an IEEE 754 expert =(
>We could attempt defaulting step to the current behavior when
decimal_place < big and fallback to any just how `FloatField` does.
I think that step > 0.001 is anyway useless in general. May be just
`.setdefault("step", "any")` exactly as in FloatField? In the face of
ambiguity, refuse the temptation to guess.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:2>
* severity: Release blocker => Normal
Comment:
It [http://jsfiddle.net/cnSsU/7/ seems to work until] 1^-18^.
IMHO [http://www.w3.org/TR/2012/WD-html5-20121025/common-
microsyntaxes.html#rules-for-parsing-floating-point-number-values the
float parsing algorithm] is quite unambiguous and the default `step`
attribute is still overridable. I think we should be safe assuming our
`step` generation mechanism works for `decimal_places <= 18`.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:3>
Comment (by matklad):
> the default step attribute is still overridable
Not really, look again at
https://github.com/django/django/blob/stable/1.6.x/django/forms/fields.py#L374
Even if I do
{{{
answer = fields.DecimalField(max_digits=50,
decimal_places=25,
widget=NumberInput(attrs={"step": "any"}))
}}}
the step gets overriden.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:4>
Comment (by charettes):
I guess we should use `setdefault` here instead of direct assignment.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:5>
Comment (by matklad):
`setdefult` defenetelly should be there.
However I think that it's still worth to check that decimal_places <= 18
and use `any` as a default otherwise(or just always use `any`).
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:6>
Comment (by claudep):
What's definitely a bug is that `step` is not overridable.
As of the number of decimal places, it's browser-dependant, and I'm less
enthousiast to do something about it.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:7>
* owner: nobody => charettes
* status: new => assigned
Comment:
I'll write a patch and fix tests for the `setdefault` behavior.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:8>
Comment (by matklad):
I would be completely happy if I could override `step`. But it's because I
'''know''' that I have to override it. Let me try to convince you for the
last time that guessing step is not a good idea. There will be three
points.
1. Suppose I know nothing about this issue and just wrote in one of my
forms `number = fields.DecimalField(max_digits=50, decimal_places=25)`. I
use firefox and the form is working OK in it. Moreover, tests are working
too. However, very soon I get a bug report that it's impossible to use
non-integer numbers in Chrome! So I have to look into the source of the
page, notice suspicious `step="0.0000000000000000000000000001"`, and find
out that it is the reason of strange behaviour. Next, I have to look
inside django's source, to find out, from where this `step` emerges. And
only then I realize that I need to override it.
2. Current default can produce invalid html.
The step attribute, if specified, must either have a value that is a
'''valid floating-point number that parses to a number that is greater
than zero''', or must have a value that is an ASCII case-insensitive match
for the string "any".
3. If I close my eyes, forget about everything in the universe and ask
myself, "what is the most reasonable default for `step`?" I hear a voice
whispering "`any`".
Also, this issue can show more often than it seems. 10^-18^ is quit a
little number, and it looks like most users won't use such a high
precision. However, it is the '''Decimal'''Field. And if someone is using
a Decimal instead of Float, it means that he cares about high precision.
So it's rather likely that he uses many decimal places. Also, python's
default prec for decimals is 28 places!
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:9>
* has_patch: 0 => 1
Comment:
Added a patch that still sets `step` as '''default''' for `max_digits <=
18` and `'any'` in the other case.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:10>
Comment (by matklad):
This looks good. I can see only one very minor caveat. If decimal_places=0
then step is equal to any, while 1 seems more reasonable.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:11>
Comment (by charettes):
I think I've found a middleground. Parsing works flawlessly in
[http://jsfiddle.net/cnSsU/12/ exponential form]. Submitting an updated
patch.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:12>
Comment (by matklad):
Looks perfect!
As a bonus, exponential form improves html readability.
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:13>
* stage: Accepted => Ready for checkin
Comment:
RFC, but please either add a comment about the rationale or refer to this
ticket. Thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:14>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"415a36947cb4b8b61230698e13cca2df9400e245"]:
{{{
#!CommitTicketReference repository=""
revision="415a36947cb4b8b61230698e13cca2df9400e245"
Fixed #20765 -- Set small values of `step` using exponential notation.
Browsers parse small factors of 10 as 0 under decimal notation.
Thanks to Trac alias matklad for the report and Claude Paroz for the
review.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:15>
Comment (by Simon Charette <charette.s@…>):
In [changeset:"9d3f7a21a337aa82d5c9ac5ef9a6a3888bff62a8"]:
{{{
#!CommitTicketReference repository=""
revision="9d3f7a21a337aa82d5c9ac5ef9a6a3888bff62a8"
[1.6.x] Fixed #20765 -- Set small values of `step` using exponential
notation.
Browsers parse small factors of 10 as 0 under decimal notation.
Thanks to Trac alias matklad for the report and Claude Paroz for the
review.
Backport of 415a36947c from master.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20765#comment:16>