当前位置: 首页 > 工具软件 > WTForms > 使用案例 >

wtforms

乜承嗣
2023-12-01

wtformsPython 的表单组件,用于表达数据的验证。

一、安装

pip3 install wtforms

二、组成

wtforms依照功能类别来说wtforms分别由以下几个类别:

  • Forms: 主要用于表单验证、字段定义、HTML生成,并把各种验证流程聚集在一起进行验证。
  • Fields: 主要负责渲染(生成HTML)和数据转换。
  • Validator:主要用于验证用户输入的数据的合法性。比如Length验证器可以用于验证输入数据的长度。
  • Widgets:html插件,允许使用者在字段中通过该字典自定义html小部件。
  • Meta:用于使用者自定义wtforms功能,例如csrf功能开启。
  • Extensions:丰富的扩展库,可以与其他框架结合使用,例如django
  • Flask 信号机制(signal

三、使用Forms进行表单验证

首先给出一个简单的示例程序,web 部分使用的是 Flask,换成 tornadoaiohttp 等都是一样的。

# coding=utf-8
from flask import Flask, request
from multidict import MultiDict
from wtforms import Form, StringField, validators, ValidationError


# 定义 app 实例
app = Flask(__name__)


# 表单验证类
class ActionForm(Form):
    action = StringField('action', [validators.DataRequired()])


@app.route("/test", methods=['POST'])
def action():
    post_data = request.json
    _form = ActionForm(MultiDict(post_data))
    if _form.validate():
        print('>>>> {} validate success'.format(post_data))
        return "form success"
    else:
        print('<<<< {}'.format(_form.errors))
        return "form validate"


if __name__ == '__main__':
    app.run(debug=True)

使用 curl 进行测试:

curl -l -H "Content-type: application/json" -X POST -d '{"action": "START"}' 127.0.0.1:5000/test
>>> form success

说明:

  • 定义了**ActionForm类,用于验证一个类型为String的字段,字段名为action**, validators.DataRequired()表示该字段必须要有,若无则无法通过验证,validators.optional()表示该参数可选;
  • post_data中有其他参数未在**ActionForm**定义的话,不会影响form的验证,直接忽略;
  • 除了StringField外,还有其他如:BooleanFieldDateFieldIntegerFieldPasswordFieldFieldListFormFieldFloatField等等,可以查看官方文档;
  • **FieldList**是一个列表字段,可以指定listfield的类型;
  • **FormField**类似一个字典字段,可以嵌套定义;
  • 初始化Form后,调用**validate()进行验证,若通过验证则返回True,否则返回False,失败的情况加Formerrors**返回所有所有验证失败的字段及失败信息;

三、自定义验证函数Costom validators

在使用过程中,会有需求对字段进行更细化的验证,比如:希望**action字段的字符串值在['START', 'CANCEL']**范围内,此时就需要编写自定义的验证函数,对字段进行追加验证。

增加一个validator,用于验证action字段在['START', 'CANCEL']范围内,若不在则抛出**ValidationError**异常:

def my_action_check(form, field):
    if field.data not in ['START', 'CANCEL']:
        raise ValidationError('action must in [START, CANCEL]')

在**ActionFormaction字段的validator列表中加入my_action_check**,wtForms会按照先后顺序调用所有的validator对字段进行验证(链式调用,某个环节失败则不继续验证

class ActionForm(Form):
    action = StringField('action', [validators.Required(), my_action_check])
  • 此时调用接口时若传入**action参数不为STARTCANCEL**,则表单无法通过验证。
  • 验证函数的form字段即为当前的form对象,可用来获取其他字段的值进行联合验证
  • 验证函数的field字段即为当前的字段对象,通过field.data来获取值

这里的my_action_check方式是定义在ActionForm类的外部,当然也可以将其定义在ActionForm类的内部,如下所示:

class ActionForm(Form):
    action = StringField('action', [validators.Required()])
        
    def validate_action(form, field):
        if field.data not in ['START', 'CANCEL']:
            raise ValidationError('action must in [START, CANCEL]') 

这两种验证方式的效果都是一样的,可以根据实际情况选择,若my_action_check具有通用性,则可就想起定义在外部,同时在在多个验证类中引用。若my_action_check是针对某个字段的特定验证,则将其定义在验证类内部方便维护。

四、自定义字段Costom Fields

有的场景下,会post复杂的json数据,wtForms自带的字段会感觉不太够用,此时可以自己定义一个字段,能灵活验证数据。如嫌**FieldList或者FormField**用起来麻烦,可以自己定义一个ListFieldDictField来验证列表和字典字段。

自定义ListField,验证数组:

class ListField(Field):

    def process_formdata(self, valuelist):
        try:
            if valuelist[0] and isinstance(valuelist[0], list):
                self.data = valuelist[0]
            else:
                raise ValidationError('list validate error')
        except:
            raise ValidationError('list validate error, exception')
            
class ActionForm(Form):
    action = StringField('action', [validators.DataRequired()])
    users = ListField('users', [validators.DataRequired()])

    def validate_action(form, field):
        if field.data not in ['START', 'CANCEL']:
            raise ValidationError('action must in [START, CANCEL]')

使用 crul 进行测试:

curl -l -H "Content-type: application/json" -X POST -d '{"action": "START", "users": ["Tracy", "Kobe", "KD"]}' 127.0.0.1:5000/test
>>> form success

users字段不传数组或数组为空则form无法通过验证

  • 自定义ListField时,需重process_formdata方法处理初始化时传入的值,值通过valuelist[0]获取,若验证通过则将值赋给self.data,那么这个字段就有值了,后续的validators就可以对此值进行验证
  • validators.DataRequired()实际做的事情就是判断字段的self.data是否为True

小结

wtForms还有一些其他用法在此就不再介绍了,翻阅文档吧。

 类似资料: