我有一个包含价格十进制字段的表单,如下所示:
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)。
答案 0 :(得分:3)
正如@mueslo正确推断的那样,这是因为默认的DecimalField
实现并未完善它收到的表单数据。它只会舍入初始数据(如默认值或模型/已保存数据)。
我们可以使用修改过的DecimalField实现轻松更改此行为,其中我们覆盖process_formdata
方法。有点像:
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)