zoukankan      html  css  js  c++  java
  • Flask-WTF

    Flask-WTF 提供了简单地 WTForms 的集成。

    官方文档:http://www.pythondoc.com/flask-wtf/index.html

    功能

    • 集成 wtforms。
    • 带有 csrf 令牌的安全表单。
    • 全局的 csrf 保护。
    • 支持验证码(Recaptcha)。
    • 与 Flask-Uploads 一起支持文件上传。
    • 国际化集成。

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

    pip install flask-wtf

    Wtforms 表单验证:

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

    from wtforms import Form,StringField
    from wtforms.validators import Length,EqualTo
    
    class RegisterForm(Form):
        name = StringField(validators=[Length(min=3,max=10,message='用户名为3~10个字符')])
        password1= StringField(validators=[Length(min=6,max=10,message='密码为3~10个字符')])
        password2 = StringField(validators=[EqualTo("password1",message='两次密码不一致')])
            form = RegisterForm(request.form)
            if form.validate():

    RegistForm传递的是request.form进去进行初始化,并且判断form.validate会返回用户提交的数据是否满足表单的验证。 

    Wtf常用验证器 

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

    • Email:验证上传的数据是否为邮箱。
    • EqualTo:验证上传的数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等。
    • InputRequired:原始数据的需要验证。如果不是特殊情况,应该使用InputRequired
    • Length:长度限制,有min和max两个值进行限制。
    • NumberRange:数字的区间,有min和max两个值限制,如果处在这两个数字之间则满足。
    • Regexp:自定义正则表达式。
    • URL:必须要是URL的形式。
    • UUID:验证UUID

    自定义验证字段:

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

    class ProfileForm(Form):
        name = wtforms.StringField('name',[validators.InputRequired()])
        def validate_name(self,field):
            #获取值:field.data
            if len(field.data) > 5:
                raise wtforms.ValidationError(u'超过5个字符')

     field就是传入 的表单提交name值

    Field常用参数:

    在使用Field的时候,经常需要传递一些参数进去,以下将对一些常用的参数进行解释:

    • label(第一个参数):Field的label的文本。
    • validators:验证器。
    • id:Field的id属性,默认不写为该属性名。
    • default:默认值。
    • widget:指定的html控件。

    常用Field:

    • BooleanField:布尔类型的Field,渲染出去是checkbox
    • FileField:文件上传Field。

        # forms.py
        from flask_wtf.file import FileField,FileAllowed,FileRequired
        class UploadForm(FlaskForm):
            avatar = FileField(u'头像:',validators=[FileRequired(),FileAllowed([])])
      
        # app.py
        @app.route('/profile/',methods=('POST','GET'))
        def profile():
            form = ProfileForm()
            if form.validate_on_submit():
                filename = secure_filename(form.avatar.data.filename)
                form.avatar.data.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
            return u'上传成功'
      
            return render_template('profile.html',form=form)
      
    • FloatField:浮点数类型的Field,但是渲染出去的时候是text的input。

    • IntegerField:整形的Field。同FloatField。

    • RadioField:radio类型的input。表单例子如下:

        # form.py
        class RegistrationForm(FlaskForm):
            gender = wtforms.RadioField(u'性别:',validators=[DataRequired()])
      

      模板文件代码如下:

        <tr>
            <td>
                {{ form.gender.label }}
            </td>
            <td>
                {% for gender in form.gender %}
                    {{ gender.label }}
                    {{ gender }}
                {% endfor %}
            </td>
        </tr>
      

      app.py文件的代码如下,给gender添加了choices

        @app.route('/register/',methods=['POST','GET'])
        def register():
            form = RegistrationForm()
            form.gender.choices = [('1',u'男'),('2',u'女')]
            if form.validate_on_submit():
                return u'success'
      
            return render_template('register.html',form=form)
      
    • SelectField:类似于RadioField。看以下示例:

        # forms.py
        class ProfileForm(FlaskForm):
            language = wtforms.SelectField('Programming Language',choices=[('cpp','C++'),('py','python'),('text','Plain Text')],validators=[DataRequired()])
      

      再来看app.py文件:

        @app.route('/profile/',methods=('POST','GET'))
        def profile():
            form = ProfileForm()
            if form.validate_on_submit():
                print form.language.data
                return u'上传成功'
            return render_template('profile.html',form=form)
      

      模板文件为:

        <form action="/profile/" method="POST">
            {{ form.csrf_token }}
            {{ form.language.label }}
            {{ form.language() }}
            <input type="submit">
        </form>
      
    • StringField:渲染到模板中的类型为<input type='text'>,并且是最基本的文本验证。

    • PasswordField:渲染出来的是一个passwordinput标签。

    • TextAreaField:渲染出来的是一个textarea

    文件上传:

    from werkzeug.datastructures import  FileStorage
    from werkzeug.utils import secure_filename
    
    @app.route('/upload/',methods=['GET','POST'])
    def upload():
        if request.method == 'GET':
            return render_template('upload.html')
        else:
            file = request.files.get('avatar')
            file.save(dst=secure_filename(file.filename))
            pass

     访问上传文件:

    @app.route('/images/<filename>/')
    def images(filename):
        return send_from_directory(directory=os.path.dirname(__file__),filename=filename)

    拾遗:

    from werkzeug.datastructures import  FileStorage,ImmutableDict,CombinedMultiDict
    from werkzeug.utils import secure_filename
    from flask_wtf.file import FileField,FileAllowed,FileRequired
    
    class UploadForm(Form):
        avatar = FileField(validators=[FileAllowed(['png','jpg','jpeg']),FileRequired()])
        desc = StringField(validators=[Required()])
    
    @app.route('/upload/',methods=['GET','POST'])
    def upload():
        if request.method == 'GET':
            return render_template('upload.html')
        else:
            form = UploadForm(CombinedMultiDict([request.form,request.files]))
            if form.validate():
                desc = form.desc.data
                file = request.files.get('avatar')
                # file.save(dst=secure_filename(file.filename))
  • 相关阅读:
    【美团技术团队文章--学习笔记】之 Java动态追踪技术探究
    mq
    为啥要读写分离
    算法 数据结构
    对扩展开放,对修改关闭
    redis 事务
    准实时数仓设计方案
    Scala Puzzlers 系列(一):占位符的使用
    【面试题】大数据开发岗位
    Hive 分区和分桶
  • 原文地址:https://www.cnblogs.com/donghaoblogs/p/10389688.html
Copyright © 2011-2022 走看看