gpt4 book ai didi

python - Flask-WTForms RadioField 自定义验证器消息不起作用

转载 作者:太空狗 更新时间:2023-10-30 00:05:40 24 4
gpt4 key购买 nike

Flask-WTForms 中,我们可以为每个字段的每个验证器提供自定义消息。但是对于 RadioField 它只显示默认消息。下面是一个例子。

>>> from wtforms import Form, RadioField, TextField
>>> from wtforms.validators import *

文本字段

>>> class MyForm(Form):
x = TextField(u'Some text', validators = [Required(message="Hello")])

错误信息

>>> form = MyForm()
>>> form.x.data
>>> form.validate()
False
>>> form.errors
{'x': ['Hello']}

因此,对于 TextField,它会显示自定义错误消息。

radio 场

>>> class MyForm(Form):
x = RadioField(choices = [(1, '1'), (2, '2')], validators = [Required(message="Hello")])

错误信息

>>> form = MyForm()
>>> form.x.data
u'None'
>>> form.validate()
False
>>> form.errors
{'x': [u'Not a valid choice']}

自定义错误消息不存在。我想,TextFieldRadioField 的验证过程是不同的,这可能就是它显示默认消息的原因。

所以我的问题是如何显示用于验证 RadioField 的自定义消息?

最佳答案

您说得对,流程不同。

因此,如果您执行 source code,则存在具有 Field 方法的 validate 基类。据说

"""
Validates the field and returns True or False. `self.errors` will
contain any errors raised during validation. This is usually only
called by `Form.validate`.

Subfields shouldn't override this, but rather override either
`pre_validate`, `post_validate` or both, depending on needs.>

:param form: The form the field belongs to.
:param extra_validators: A sequence of extra validators to run.
"""

验证过程是pre_validate() -> validate() -> post_validate()(调用pre_validate -> 运行验证器 -> 调用 post_validate)

您可以猜到,RadioField 有它自己的 pre_validate() 方法,但基本上是 SelectField 的方法。然后当 RadioField 继承自 SelectField 时,它也有它。

def pre_validate(self, form):
for v, _ in self.choices:
if self.data == v:
break
else:
raise ValueError(self.gettext('Not a valid choice'))

这就是为什么您在 wtforms.validators.Required() 验证器上得到 'Not a valid choice' 错误而不是您的自定义错误的原因,因为它只是没有通过 pre_validate() 就停止了。

注意:Required 验证器已弃用并将在 WTForms 3.0 中删除,并且在 that 拉取请求中他们已经删除了它的用法。代替 Required() 验证器,使用 DataRequired()

更新:由于您将验证器添加到字段中,您仍然应该能够得到错误。因为 pre_validate() 仅引发 ValueError 它不会停止 validate()

# Call pre_validate
try:
self.pre_validate(form)
except StopValidation as e:
if e.args and e.args[0]:
self.errors.append(e.args[0])
stop_validation = True
except ValueError as e:
self.errors.append(e.args[0])

然后去

# Run validators
if not stop_validation:
chain = itertools.chain(self.validators, extra_validators)
stop_validation = self._run_validation_chain(form, chain)

这里是您的验证器存在并且应该将新错误添加到错误列表(form.x.error),但是它将 None 转换为 ' None',所以你的 form.x.data 变成了 'None'(str 类型),现在它变成了 __call__

def __call__(self, form, field):
if not field.data or isinstance(field.data, string_types) and not field.data.strip():
if self.message is None:
message = field.gettext('This field is required.')
else:
message = self.message

field.errors[:] = []
raise StopValidation(message)

条件 not field.dataFalse,因为 field.data'None'。为什么 SelectField 的数据从 None 转换为 'None' 及其相关项在 Issue on GitHub 中有解释,当 Pull Request 合并到大师。

关于python - Flask-WTForms RadioField 自定义验证器消息不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39696563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com