WTForms自定义验证方法(行内验证器)是如何被调用的?
source link: https://greyli.com/how-custom-validator-work-in-wtforms/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
WTForms自定义验证方法(行内验证器)是如何被调用的?
这篇文章基于我在知乎上的这个回答,进行了相应的简化处理,放到这里做个备份。
万能的回答
答案在源码里。
简单的回答
WTForms会在你对表单实例调用Form.validate()方法时收集所有的行内验证方法,然后在对每个字段调用Field.validate()方法验证时将这些自定义行内验证方法一并和通过validators参数传入的验证器列表一起调用,进行验证。因为WTForms在调用时把对应的field作为参数传入了行内验证方法,所以你可以在自定义验证方法中通过field.data获取对应字段的数据。
深入的回答
WTForms会在你对表单实例调用Form.validate()方法时收集所有的行内验证方法。在Form类中的validate()方法定义中,你可以看到WTForms是如何收集这些行内验证方法的:
源码位置:https://github.com/wtforms/wtforms/blob/2.2.1/wtforms/form.py#L305-L308
这里迭代所有的字段属性,然后表单类中是否包含validate_字段名
形式的方法。如果有,那么就添加到extra字段里,这个字段被传递到BaseForm类的validate()方法中。在BaseForm类的validate()方法中,WTForms迭代所有字段,并对每个字段调用Field.validate()方法验证字段,继续传入自定义的行内验证方法:
源码位置:https://github.com/wtforms/wtforms/blob/2.2.1/wtforms/form.py#L134-L154
而在字段基类Field的validate()方法中,WTForms使用itertool模块提供的chain()函数把你实例化字段类时传入的验证器(self.validators
)和自定义行内验证器(extra_validators
)连接到一起:
源码位置:https://github.com/wtforms/wtforms/blob/2.2.1/wtforms/fields/core.py#L204-L206
连接起来的所有验证器赋值为chain变量,并传入到self._run_validation_chain(form, chain)
进行进一步调用:
源码位置:https://github.com/wtforms/wtforms/blob/2.2.1/wtforms/fields/core.py#L226
这个方法迭代所有的验证器对字段数据进行验证。关键在于validator(form, self),可以看到这里传入了第二个参数self,即Field类本身,这也是为什么你可以在自定义验证方法中通过field.data获取当前字段数据。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK