以下是部分源代码
# wtforms.fields.core.py | version: Flask-WTF 0.14.3
class Field(object):
errors = tuple()
...
def validate(self, form, extra_validators=tuple()):
self.errors = list(self.process_errors)
stop_validation = False
self.check_validators(extra_validators)
try:
self.pre_validate(form) # <---------- focus here
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) # <-- It will run ``InputRequired, YourValidators1, YourValidators2, validate_username`` (see the example code)
# Call post_validate
try:
self.post_validate(form, stop_validation) # <---------- focus here
except ValueError as e:
self.errors.append(e.args[0])
return len(self.errors) == 0
我给你举个例子post_validate
(pre_validate
非常相似,我相信你可以自己做)
from flask_wtf import FlaskForm, Form
from wtforms import StringField, ValidationError, StopValidation
from wtforms.validators import InputRequired
from typing import List
class StateStringField(StringField):
ok_msg_list: List = None # Because class ``wtforms.fields.core.Field`` are not existed any attributes I like, so I create one.
def post_validate(self, form: Form, stop_validation: bool):
if self.ok_msg_list is None:
self.ok_msg_list = []
if stop_validation:
return
if not 'errors': # assume no errors...
raise ValueError('...')
else:
self.ok_msg_list.append('OK')
class UserForm(FlaskForm):
username = StateStringField('User',
validators=[InputRequired(),
# YourValidators2, YourValidators3
])
def validate_username(self, field: StringField):
if len(field.data) > 50:
raise StopValidation('Name must be less than 50 characters')
<!-- templates/auth/register.html-->
<form method="post">
{{ form.hidden_tag() }}
<p>{{ form.username.label }} {{ form.username()|safe }}
{% if form.username.errors %}
{% for error in form.username.errors %}
<p style="color:red;">{{ error }}<p>
{% endfor %}
{% endif %}
{% if form.username['ok_msg_list'] %} <!-- similar as python: if hasattr('ok_msg_list') -->
{% for ok_msg in form.username.ok_msg_list %}
<span style="color:blue;">{{ ok_msg|safe }}</span>
{% endfor %}
{% endif %}
</p>
</form>
概括
您可以在执行完所有post_validate
验证后想要执行另一次验证时使用。(个人认为与.post_validate
finally
在我的示例中,当用户验证所有验证都正确时,旁边会出现一条 OK 消息。