As @mueslo correctly deduced, this is because the default implementation of DecimalField does not complete the form data that it receives. It only rounds the source data (both by default and by model / saved data).
We can easily change this behavior with a modified DecimalField implementation in which we override the process_formdata method. Somewhat:
from wtforms import DecimalField class BetterDecimalField(DecimalField): """ Very similar to WTForms DecimalField, except with the option of rounding the data always. """ def __init__(self, label=None, validators=None, places=2, rounding=None, round_always=False, **kwargs): super(BetterDecimalField, self).__init__( label=label, validators=validators, places=places, rounding= rounding, **kwargs) self.round_always = round_always def process_formdata(self, valuelist): if valuelist: try: self.data = decimal.Decimal(valuelist[0]) if self.round_always and hasattr(self.data, 'quantize'): exp = decimal.Decimal('.1') ** self.places if self.rounding is None: quantized = self.data.quantize(exp) else: quantized = self.data.quantize( exp, rounding=self.rounding) self.data = quantized except (decimal.InvalidOperation, ValueError): self.data = None raise ValueError(self.gettext('Not a valid decimal value'))
Usage example:
rounding_field = BetterDecimalField(round_always=True)
Gist
source share