Rounding a decimal field in WTForms

I have a form containing a decimal price field, for example:

from flask.ext.wtf import Form import wtforms from wtforms.validators import DataRequired from decimal import ROUND_HALF_UP class AddListingBase(Form): title = wtforms.StringField(validators=[DataRequired()]) details = wtforms.TextAreaField(validators=[DataRequired()]) price = wtforms.DecimalField(places=2, rounding=ROUND_HALF_UP, validators=[DataRequired()]) 

When I submit the form, the decimal value appears rounded to two decimal places, but this never happens. I always get the value as indicated (e.g. 99.853 - 99.853, not 99.85, as it should be).

+5
source share
1 answer

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

+3
source

Source: https://habr.com/ru/post/1210406/


All Articles