WTForms中的十进制字段舍入 [英] Decimal field rounding in WTForms

查看:76
本文介绍了WTForms中的十进制字段舍入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含价格十进制字段的表单,如下所示:

I have a form that contains a price decimal field, like so:

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()])

当我提交表单时,十进制值被假定为四舍五入到小数点后两位,但这从来没有发生过.我总是得到指定的值(例如99.853是99.853,而不是应该的99.85).

When I submit the form, the decimal value is suppoosed to be rounded to 2 decimal places, but that never happens. I always get the value as it was specified (e.g. 99.853 is 99.853, not 99.85 as it should be).

推荐答案

由于@mueslo可以正确推断,这是因为默认的 DecimalField 实现无法对 form数据进行四舍五入它收到.只会四舍五入初始数据(如默认值模型/保存的数据).

As @mueslo has rightly inferred, this is because the default DecimalField implementation does not round off the form data it receives. It only rounds off the initial data (as in defaults, or model/saved data).

我们可以通过修改后的DecimalField实现轻松更改此行为,其中我们覆盖了 process_formdata 方法.像这样:

We can easily change this behavior with a modified DecimalField implementation, wherein we override the process_formdata method. Somewhat like so:

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'))

示例用法:

rounding_field = BetterDecimalField(round_always=True)

要点

这篇关于WTForms中的十进制字段舍入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆