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

Flask——Flask-WTF表单验证,文件上传

松高爽
2023-12-01

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

pip install flask-wtf

Flask表单验证

field字段

  • StringField:字符串字段
  • PasswordField:密码字段,自动转换黑点
  • IntegerField:整型字段,要求输入必须为整数
  • DateField:要求输入格式必须是 datetime.date
  • FloatField:要求输入是浮点数
  • BooleanField:复选框,值为 True或False
  • RadioField:单选框
  • SelectField:下拉列表
  • MultipleSelectField:可选多个值的下拉列表

Validators验证器

用于验证用户输入的数据的合法性

  • Email:验证邮箱的合法性,首次使用要安装email_validator pip install email_validator
  • EqualTo:比较两个字段的值是否一致,一般用在确认密码上。
  • length:验证字符串的输入长度,有两个参数(min= ,max= )指定设置长度的最大值和最小值
  • Regexp:自定义正则表达式验证
  • URL:验证是否为Github的URL
  • Required:必填字段
  • NumberRange:验证是否是规定范围内的数字,两个参数(min,max)

forms.py

from wtforms import Form, StringField, validators,IntegerField, ValidationError,BooleanField
from wtforms.validators import length, Regexp, EqualTo, Email, NumberRange, InputRequired, URL

class emailForm(Form):
    email = StringField('邮箱:',validators=[Email()])
    #  pip install email_validator

    age = IntegerField('年龄:',validators=[NumberRange(1,120)])

    username = StringField('用户名:',validators=[length(min=3, max=10, message='请输入3-10位长度的用户名'),InputRequired(message='必须填写用户名')])
    password = StringField('密码:', validators=[length(min=8, max=20, message='请输入8-20位长度的密码')])
    password_repeat = StringField('确认密码:', validators=[ EqualTo('password', message="两次密码不一致")])

    phone = StringField('联系电话:',validators=[Regexp(r'1[358]\d{9}',message='请输入有效的手机号')])
    info = StringField('GitHub主页地址:',validators=[URL(message='请输入有效的Git地址')])
    captcha = StringField('验证码:',validators=[length(min=4,max=4)])
    def validate_captcha(self,field):
        # 这里的名字是固定格式
        print(type(field))
        if field.data != '8jsk':
            raise ValidationError('验证码错误')

app.py

from flask import Flask, request, render_template
from flask.views import MethodView

from forms import emailForm

app = Flask(__name__)


@app.route('/')
def index():
    return "主页"
    
class DemoView(MethodView):

    def get(self):
        form = emailForm(request.form)
        print("!!!")
        return render_template('other.html', form = form )

    def post(self):
        form = emailForm(request.form)

        if form.validate():
            return "注册成功"
        else:
            print(form.errors)
            for value in form.errors.values():
                for l in value:
                    return l
             # 这样可以输出 message里面的数据


app.add_url_rule('/email/', view_func=DemoView.as_view('DemoView'))

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

templates/other.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    <table>
        <tr>
            <td>{{ form.username.label }}</td>
            <td>{{ form.username() }}</td>

        </tr>
        <tr>
            <td>{{form.password.label}}</td>
            <td>{{ form.password()}}</td>

        </tr>
        <tr>
            <td>{{form.password_repeat.label}}</td>
            <td>{{form.password_repeat()}}</td>

        </tr>
        <tr>
            <td>{{form.age.label}}</td>
            <td>{{form.age()}}</td>

        </tr>
        <tr>
            <td>{{form.email.label}}</td>
            <td>{{form.email()}}</td>

        </tr>
        <tr>
            <td>{{form.info.label}}</td>
            <td>{{form.info()}}</td>

        </tr>
        <tr>
            <td>{{form.phone.label}}</td>
            <td>{{form.phone()}}</td>

        </tr>
        <tr>
            <td>{{form.captcha.label}}</td>
            <td>{{form.captcha()}}</td>

        </tr>

    </table>
    <input type="submit" value="提交">
</form>

</body>
</html>

CSRF保护

from flask_wtf import CSRFProtect

app = Flask(__name__)
CSRFProtect(app)

form表单_____________________________________
<input type="hidden" name="csrf_token" value="{{csrf_token()}}">

文件上传

flask_upload.py

from flask import Flask, request, render_template, send_from_directory, Response
import os
from werkzeug.utils import secure_filename
from forms import UploadForm
app = Flask(__name__)

@app.route("/")
def index():
    return "首页"

@app.route("/upload/",methods=['GET','POST'])
def upload():
    if request.method =='GET':
        return render_template('upload.html')
    else:

        picture = request.files.get('picture')
        filename = secure_filename(picture.filename)
        print(filename)
        picture.save(os.path.join('images', filename))
        return "文件上传成功"



@app.route('/images/<filename>/')
def get_image(filename):
    return send_from_directory('images',filename)

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

forms.py

from wtforms import Form, FileField
from flask_wtf.file import FileAllowed, FileRequired

class UploadForm(Form):
    # FileRequired 文件必须传
    # FileAllowed 允许上传的类型
    picture = FileField(validators=[FileRequired(), FileAllowed(['jpg', 'png', 'gif'])])

templates/upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
    头像:<input type="file" name="picture">
    <input type="submit" value="上传">
</form>
</body>
</html>
 类似资料: