flask-WTForms

Posted fengzi759

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask-WTForms相关的知识,希望对你有一定的参考价值。

  1. WTForms表单验证基本使用

    • Flask-WTF是简化了WTForms操作的一个第三方库,WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板。当然还包括一些其他的功能:CSRF保护,文件上传等。安装Flask-WTF默认也会安装WTForms,因此使用以下命令来安装Flask-WTF

      • pip install flask-wtf

    • 这个库一般有两个作用:第一个就是做表单验证,把用户提交上来的数据进行验证是否合理。第二个就是做模板渲染

  2. 表单验证:

    • 安装完Flask-WTF后。来看下第一个功能,就是用表单来做数据验证,现在有一个forms.py文件,然后再里面创建一个RegistForm的注册验证表单:

      • 1.自定义一个表单类,继承自wtforms.Form类

      • 2.定义好需要验证的字段,字段的名字必须和模板中那些需要验证的input标签的name属性值保持一致

      • 3.在需要验证的字段上,需要指定好具体 的数据类型

      • 4.在相关的字段上,指定验证器

      • 5.以后再视图中,就只需要使用这个表单类的对象,并且把需要验证的数据,也就是request.form传给这个表单类,以后调用form.validate()方法,如果返回True,那么代表用户输入的数据都是合法的,否则代表用户输入的数据是有问题的。如果验证失败了,那么可以通过form.errors来获取具体的错误信息

      • 示例代码如下

        • RegistForm类中的代码
          
          + 导入库
            + from wtforms import Form,StringField
            + from wtforms.validators import Length,EqualTo
          + class RegistForm(Form)
            + name = StringField(validators=[length(min-4,max-25)])
            + email = StringField(validators=[email()])
            + password = StringField(validators = [DataRequired(),length(min=6,max=10),EqualTo(confirm)])
            + confirm = StringField()
          + 视图函数中的代码
            + form  = RegistForm(request.form)
            + if form.validate():    
              + return  success
            + else:    
              + print(form.errors)   
              + return  fail
      • 再这里面指定了需要上传的参数,并且指定了验证器,比如name的长度应该在4~25之间。email必须要满足邮箱的格式。password长度必须在6~10之间,并且应该和confirm相等才能通过验证。

  3. 常用的验证器:

    • 数据发送过来,经过表单验证,因此需要验证器来进行验证,以下对一些常用的内置验证器进行讲解:

      • Emai:验证上传的数据是否为邮箱

      • EqualTo: 验证上传的数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等

      • InputRequired:原始数据的需要验证。如果不是特殊情况,应该使用InputRequired

        • 如果传值了就验证成功,如果没有传值就验证失败

      • Length:长度限制,有min和max两个值进行限制

      • NumberRange: 数字的区间,有min和max两个值限制,如果处在这两个数字之间则满足

      • Regexp: 自定义正则表达式

      • URL:必须要是URL的形式

      • UUID:验证UUID

      • 示例代码如下

        • email = StringField(validators=[email()])
  4. 自定义验证字段:

    • 使用validate_fieldname(self,field)可以对某个字段进行更加详细的验证

    • 如果想要对表单中的某个字段进行更细化的验证,那么可以针对这个字段进行单独的验证

      • 步骤如下:

        • 1.定义一个方法,方法的名字规则是: validate_字段名(self,filed)

        • 2.在方法中,使用field.data可以获取到这个字段具体的值。也就是前端传过来的值

        • 3.如果数据满足条件,那么可以什么都不做,如果验证失败,那么应该抛出一个‘wtforms.validators.ValidationError‘的异常,并且把验证失败的信息传到这个异常类中

        • 4.示例代码如下

          • class LoginForm(Form):
            ?
            + captcha = StringField(validators = [Length(4,4)])
            + def validate_captcha(self,field)
              + if field.data!=1234:
                + raise  ValidationError("验证码错误!")
  5. 渲染模板:

    • form还可以渲染模板,让你少写了一丢丢的代码,比如重写以上列子,RegistForm表单代码如下

      • class RegistForm(Form):
        ?
        + name = StringField(u用户名,validators=[length(min-4,max-25)])
        + email = StringField(u邮箱,validators=[email()])
        + password = StringField(u密码,validators = [DataRequired(),length(min=6,max=10),EqualTo(confirm)])
        + confirm = StringField(u确认密码)
      • 以上增增加了第一个位置参数,用来在html文件中, 做标签提示作用

    • 在app中的视图函数中,修改如下

      • + @app.route(setting,methods=[POST,GET])
        + def regist():
          + if  request.method ==GET
            + form = RegistForm(request.form)
            + reture render_template(setting.html,form=form)
      • 以上唯一的不同是在渲染模板的时候传入了form表单参数进行,这样在模板中就可以使用表单form变量了

    • 在html文件中

      • {{form.name.label}} name 是定义表单的字段 form.name.label相当于我们给表单起的名字

      • {{form.name()}} 相当于input表单 根据表单里面的字段 计算机自动选择不同的input标签

  6. 文件上传以及访问上传的文件

    • 1.在模板中,form表单中,需要指定‘encotype=‘multipart/form-data‘才能上传文件

    • 2.在后台如果想要获取上传的文件,那么应该使用‘request.files.get(‘avatar‘)‘来获取

    • 3.保存文件之前,先要使用werkzing.utils.secure_filename来对上传上来的文件名进行一个过滤,这样才能保证不会有安全 问题。 使用avatar.filename获取文件的名字

    • 4.获取到上传上来的文件后,使用avatar.save(路径)来保存文件

    • 5.从服务器上读取文件,应该定义一个url与视图函数,来获取指定的文件,在这个视图函数中,使用send_from_directory(文件的目录,文件名)来获取 如果是图片,第二个参数在URL中就要传图片的名字

    • 6.示例代码如下

      • + UPLOAD_URL = os.path.join(os.path.dirname(__ file__),static)
        + @app.route(/upload/,methods=[GET,POST])
        + def upload():
          + if request.method ==GET:
            + return  render_template(upload.html)
          + else:
            + #获取描述信息
            + desc = request.form.get("desc")  #desc是模板里面input标签里面的name属性
            + avatar = request.files.get(avatar)
            + filename = secure_filename(avatar.filename)
            + avatar.sava(os.path.join(UPLOAD_PATH,filename))
            + print(desc)
            + return  文件上传成功
        + @app.route(/images/< filename>/)
        + def get_image(filename):
          + return  send_from_directory(UPLOAD_PATH,filename)
  7. 使用flask_wtf验证上传的文件

    • 1.定义表单的时候,对文件的字段,需要采用 FileField这个类型

    • 2.验证器应该从flask_wtf.file中导入 flask_wtf.file.FileRequired是用来验证文件上传是否为空,flask_wtf.file.FileAllowed用来验证上传的文件的后缀名 (传的是一个列表)

    • 3.在视图文件中,使用werkzeug.datastructures import CombinedMultiDict(传的是一个列表) 来把request.form与request.files来进行合并,再传给表单来验证 示例代码如下

      • + form=UploadForm(CombinedMultiDict([request.form,request.files]))
        + UploadForm是我们定义的表的名字
        + 也可以直接从form里面获取数据
          + desc = request.form.get(desc)
          + avatar = request.files.get(avatar) 
          + 等价于
          + desc = form.desc.data
          + avarar = form.avarar .data

以上是关于flask-WTForms的主要内容,如果未能解决你的问题,请参考以下文章

6---Flask-WTForms

flask-wtforms

flask-WTForms

Flask-WTForms

flask-wtforms。 QuerySelectField RuntimeError

如何使 Flask-WTForms 从标签名称列表中动态更新标签?