DecimalField: Semantics of max_digits in combination with decimal_places confusing and perhaps wrong
|Reported by:||theevilgeek||Owned by:||elbarto|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
In attempting to capture fixed point decimal values in the range of .0000 to .9999, I created a DecimalField as follows:
value = forms.DecimalField(max_digits=4, decimal_places=4)
However, it seems that any decimal submitted is first normalized to include a leading "0." should no other non-fractional
digits be provided.
The presence of this additional "0." causes the input to instead resemble 0.XXXX. However, since decimal_places = 4
and max_digits = 4, no input will successfully validate-- the leading zero simply hasn't been accounted for.
- irc:Gulopine and irc:Magus suggest that this behavior is not a problem: a properly formatted decimal lacking a whole component incorporates a leading "0."; thus, the user should anticipate this extra digit and plan accordingly.
However, the documentation for the DecimalField (http://www.djangoproject.com/documentation/model-api/#decimalfield [treating the model and newforms fields as being interchangeable]) indicates that the field stores a "A fixed-precision decimal number". As fixed-precision (or fixed-point) decimal notation usually implies exacting control over the number of positions before and after the decimal point that will be incorporated in a representation of the data (http://en.wikipedia.org/wiki/Fixed-point_arithmetic), it seems reasonable to expect that the DecimalField will exactingly respect the max_digits and decimal_places arguments to the same effect. Thus, I feel that the exhibited behavior is, at the least, somewhat surprising.
- irc:Gulopine suggests that DecimalField might be altered to raise an ImproperlyConfigured error if max_digits <= decimal_places.
- The DecimalField documentation might be enhanced to explicitly state that a leading "0." will be tacked onto any decimal numbers lacking whole digits and that this leading zero must be accounted for when specifying max_digits and decimal_places.
- The behavior of DecimalField is altered such that max_digits and decimal_places are strictly enforced.
Finally, it is worth noting that the examples in the documentation for DecimalField only reinforce the expectation of strict enforcement:
"For example, to store numbers up to 999 with a resolution of 2 decimal places, you’d use: models.DecimalField(..., max_digits=5, decimal_places=2)"