简体   繁体   English

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

[英]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. 我想, TextFieldRadioField验证将是不同的过程,可能就是它显示默认消息的原因。

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.dataFalse ,因为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.

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