繁体   English   中英

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

[英]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']}

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

所以我的问题是如何显示自定义消息以验证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.dataFalse ,因为field.data'None' 为什么SelectField及其相关的数据从None转换为'None' 在GitHub上的问题中进行了解释,并且当Pull Request将在master中合并时可能会修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM