[英]Flask-WTForms RadioField custom validator message doesn't work
在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
它会显示自定义错误消息。
RadioField
>>> 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']}
自定义错误消息不存在。 我想, TextField
和RadioField
验证将是不同的过程,可能就是它显示默认消息的原因。
所以我的问题是如何显示自定义消息以验证RadioField
?
你是对的,这个过程是不同的。
因此,如果你去做源代码,那么有基类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中删除,并且在该 pull请求中他们已经删除了它的用法。 而不是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.data
为False
,因为field.data
为'None'
。 为什么SelectField
及其相关的数据从None
转换为'None'
在GitHub上的问题中进行了解释,并且当Pull Request将在master中合并时可能会修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.