Rat*_*Don 6 python flask flask-wtforms
在中Flask-WTForms,我们可以为每个字段的每个验证器提供自定义消息。但是因为RadioField它仅显示默认消息。下面是一个例子。
>>> from wtforms import Form, RadioField, TextField
>>> from wtforms.validators import *
Run Code Online (Sandbox Code Playgroud)
文本域
>>> class MyForm(Form):
x = TextField(u'Some text', validators = [Required(message="Hello")])
Run Code Online (Sandbox Code Playgroud)
错误信息
>>> form = MyForm()
>>> form.x.data
>>> form.validate()
False
>>> form.errors
{'x': ['Hello']}
Run Code Online (Sandbox Code Playgroud)
因此,TextField它显示了自定义错误消息。
无线电场
>>> class MyForm(Form):
x = RadioField(choices = [(1, '1'), (2, '2')], validators = [Required(message="Hello")])
Run Code Online (Sandbox Code Playgroud)
错误信息
>>> form = MyForm()
>>> form.x.data
u'None'
>>> form.validate()
False
>>> form.errors
{'x': [u'Not a valid choice']}
Run Code Online (Sandbox Code Playgroud)
自定义错误消息不存在。我想,对于验证TextField和RadioField将是不同的过程,可能这就是为什么它显示默认的消息。
所以我的问题是如何显示自定义消息以验证RadioField?
你说得对,这个过程是不同的。
因此,如果您执行源代码,则有Field带有validate方法的基类。据说
Run Code Online (Sandbox Code Playgroud)""" 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()(Call pre_validate-> Run validators -> Call post_validate)
你可以猜到,RadioField有它自己的pre_validate()方法,但基本上SelectField是一个。然后什么时候RadioField继承SelectField它也有它。
Run Code Online (Sandbox Code Playgroud)def pre_validate(self, form): for v, _ in self.choices: if self.data == v: break else: raise ValueError(self.gettext('Not a valid choice'))
所以这就是为什么你'Not a valid choice'在wtforms.validators.Required()验证器上得到错误而不是你的自定义错误,因为它只是没有通过pre_validate()它就停止了。
注意:Required验证器已弃用,将在 WTForms 3.0 中删除,并且在该拉取请求中,他们已经删除了它的用法。而不是Required()验证器,使用DataRequired()
更新:由于您将验证器添加到字段中,您仍然应该能够得到您的错误。因为因为pre_validate()只加注ValueError它不会停止validate()
Run Code Online (Sandbox Code Playgroud)# 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 Code Online (Sandbox Code Playgroud)# 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__
Run Code Online (Sandbox Code Playgroud)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'。为什么数据从None到'None'forSelectField及其相关数据在 GitHub 上的问题中进行了解释,并且可能会在Pull Request合并到 master 中时得到修复。