[英]Flask-WTForms RadioField custom validator message doesn't work
In Flask-WTForms
, we can give a custom message for each validator for each field. 在
Flask-WTForms
,我们可以为每个字段的每个验证器提供自定义消息。 But for RadioField
it shows the default message only. 但是对于
RadioField
它只显示默认消息。 Below is an example. 以下是一个例子。
>>> from wtforms import Form, RadioField, TextField
>>> from wtforms.validators import *
TextField 文本域
>>> class MyForm(Form):
x = TextField(u'Some text', validators = [Required(message="Hello")])
Error Message 错误信息
>>> form = MyForm()
>>> form.x.data
>>> form.validate()
False
>>> form.errors
{'x': ['Hello']}
So for a TextField
it shows the custom error message. 因此,对于
TextField
它会显示自定义错误消息。
RadioField RadioField
>>> class MyForm(Form):
x = RadioField(choices = [(1, '1'), (2, '2')], validators = [Required(message="Hello")])
Error Message 错误信息
>>> form = MyForm()
>>> form.x.data
u'None'
>>> form.validate()
False
>>> form.errors
{'x': [u'Not a valid choice']}
The custom error message is not there. 自定义错误消息不存在。 I guess, validation for
TextField
and RadioField
will be different process and may be that's why it's showing the default message. 我想,
TextField
和RadioField
验证将是不同的过程,可能就是它显示默认消息的原因。
So my Question is How to show a custom message for the validation of a RadioField
? 所以我的问题是如何显示自定义消息以验证
RadioField
?
You are right about that the process is different. 你是对的,这个过程是不同的。
So if you go do source code there is base Field
class with validate
method. 因此,如果你去做源代码,那么有基类
Field
类和validate
方法。 It's said 据说
""" 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. """
And the procedure of validation is pre_validate()
-> validate()
-> post_validate()
(Call pre_validate
-> Run validators -> Call post_validate
) 验证的过程是
pre_validate()
- > validate()
- > post_validate()
(调用pre_validate
- >运行验证器 - >调用post_validate
)
As you can guess, RadioField
has it's own pre_validate()
method, but basically SelectField
's one. 你可以猜到,
RadioField
有自己的pre_validate()
方法,但基本上是SelectField
的方法。 And then when RadioField
is inherit from SelectField
it has it too. 然后当
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'))
So that's why you get 'Not a valid choice'
error instead of your custom one, on wtforms.validators.Required()
validator, 这就是为什么你在
wtforms.validators.Required()
验证器上得到'Not a valid choice'
而不是你的自定义错误, because it just didn't go through the pre_validate()
and it stops. 因为它只是没有通过
pre_validate()
而停止。
Note : Required
validator is depracated and will be removed in WTForms 3.0, and in that pull request they already removed it's usage. 注意 :
Required
验证器被删除并将在WTForms 3.0中删除,并且在该 pull请求中他们已经删除了它的用法。 Instead of Required()
validator, use DataRequired()
而不是
Required()
验证器,使用DataRequired()
UPDATE : Since you add your validator to field you still should be able to get your error. 更新 :由于您将验证器添加到字段,您仍然应该能够得到错误。 Because since
pre_validate()
raises only ValueError
it doesn't stop validate()
因为
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])
And then it goes to 然后它去了
# Run validators if not stop_validation: chain = itertools.chain(self.validators, extra_validators) stop_validation = self._run_validation_chain(form, chain)
And here is your validator exists and should add new error to the list of errors( form.x.error
), however it converts None
to 'None'
, so your form.x.data
becomes 'None'
( str
type), and now it goes to __call__
这里是您的验证器存在并且应该在错误列表中添加新错误(
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)
And the condition not field.data
is False
, because field.data
is 'None'
. 条件
not field.data
为False
,因为field.data
为'None'
。 Why data convert from None
to 'None'
for SelectField
and its related ones is explained in Issue on GitHub and probably be fixed when Pull Request will be merged in master. 为什么
SelectField
及其相关的数据从None
转换为'None'
在GitHub上的问题中进行了解释,并且当Pull Request将在master中合并时可能会修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.