【发布时间】:2013-02-28 06:35:13
【问题描述】:
看看这个例子
class MyForm(ForM):
...snip...
quantity = DecimalField(u'Quantity', [NumberRange(1, 8)])
...snip...
如果用户合作并输入可以强制转换为数字类型的内容,这会很好地工作。但是,如果用户在浏览器的此字段中输入“asdf”,那么当我尝试在浏览器中呈现它时,DecimalField 会抛出 Type Error。
以下是回溯的相关部分:
Traceback (most recent call last):
File "/path/to/app/venv/local/lib/python2.7/site-packages/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "/path/to/app/www/templates/submodule/user/submission.html", line 26, in block "submodule_content"
{{form.quantity}}
File "/path/to/app/venv/local/lib/python2.7/site-packages/wtforms/fields/core.py", line 139, in __call__
return self.widget(self, **kwargs)
File "/path/to/app/venv/local/lib/python2.7/site-packages/wtforms/widgets/core.py", line 123, in __call__
kwargs['value'] = field._value()
File "/path/to/app/venv/local/lib/python2.7/site-packages/wtforms/fields/core.py", line 542, in _value
return format % self.data
TypeError: a float is required
我希望字段本身添加一个错误,而不是这种行为,以便我仍然可以渲染 t。
我目前的解决方案包括使用TextField 而不是DecimalField 并提供IsNumeric 验证器,其调用方法如下:
def __call__(self, form, field):
if field.data:
try:
field.data = float(field.data)
except ValueError as e:
raise ValidationError(self.message)
这几乎完美无缺,是我目前的解决方案,但肯定有一种 wtforms 惯用的方式来做到这一点。
【问题讨论】:
-
您如何向表单提供表单数据(您如何构建它)?它是使用表单数据多字典提供的吗?如果是这样,则不应发生此错误,因为不应将数据强制转换为
.data属性。这通常发生在人们将原始表单数据作为 **kwargs 传递时,这应该只用于已经强制的数据。 -
是的,这是使用 **kwargs 样式。 **kwargs 的文档中没有任何内容表明它们应该已经被强制,并且使用 web.py(可能还有其他 Web 框架),这就是返回参数的方式。应该采取什么强制措施,是否有理由认为 **kwargs 的处理方式与 multi-dict 不同?大多数情况下,最好在文档中明确说明。
标签: python wtforms type-coercion