尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flask入门教程(十二):表单处理——从基础到Flask-WTF完整实践

Flask入门教程(十二):表单处理——从基础到Flask-WTF完整实践 1. 基本表单处理Flask提供了直接处理表单数据的方式使用request对象来获取提交的数据。创建HTML表单templates/form.html!DOCTYPE html html head titleForm Example/title /head body form action/submit methodpost label fornameName:/label input typetext idname namename br label foremailEmail:/label input typeemail idemail nameemail br input typesubmit valueSubmit /form /body /htmlaction/submit表单数据提交到/submit路径methodpost使用POST方法提交数据敏感数据不应使用GET处理表单数据app.pyfrom flask import Flask, render_template, request app Flask(__name__) app.route(/) def form(): return render_template(form.html) app.route(/submit, methods[POST]) def submit(): name request.form.get(name) email request.form.get(email) return fName: {name}, Email: {email} if __name__ __main__: app.run(debugTrue)2. 使用Flask-WTF扩展Flask-WTF是一个封装了WTForms的扩展提供了表单处理和验证的功能使得表单处理更加简洁和强大。安装Flask-WTFpip install flask-wtf配置与定义表单app.pyfrom flask import Flask, render_template, redirect, url_for from flask_wtf import FlaskForm from wtforms import StringField, EmailField, SubmitField from wtforms.validators import DataRequired, Email app Flask(__name__) app.secret_key your_secret_key # CSRF保护需要密钥 class MyForm(FlaskForm): name StringField(Name, validators[DataRequired()]) email EmailField(Email, validators[DataRequired(), Email()]) submit SubmitField(Submit) app.route(/, methods[GET, POST]) def form(): form MyForm() if form.validate_on_submit(): name form.name.data email form.email.data return fName: {name}, Email: {email} return render_template(form.html, formform)模板中渲染WTFormstemplates/form.html!DOCTYPE html html head titleForm Example/title /head body form methodpost {{ form.hidden_tag() }} div {{ form.name.label }}br {{ form.name(size32) }} /div div {{ form.email.label }}br {{ form.email(size32) }} /div div {{ form.submit() }} /div /form /body /html模板语法作用{{ form.hidden_tag() }}生成CSRF令牌隐藏字段{{ form.name.label }}渲染字段的标签{{ form.name(size32) }}渲染字段控件可传入HTML属性{{ form.submit() }}渲染提交按钮3. 常用字段类型WTForms提供了丰富的字段类型覆盖了绝大多数表单场景字段类说明HTML渲染StringField文本输入input typetextEmailField邮箱输入input typeemailPasswordField密码输入input typepasswordIntegerField整数输入input typenumberFloatField浮点数输入input typenumber stepanyBooleanField复选框input typecheckboxSelectField下拉选择selectRadioField单选按钮input typeradioTextAreaField多行文本textareaSubmitField提交按钮input typesubmitFileField文件上传input typefileDateField日期输入input typedateDateTimeField日期时间输入input typedatetime-local完整表单示例from wtforms import StringField, PasswordField, BooleanField, SelectField, TextAreaField, SubmitField from wtforms.validators import DataRequired, Email, Length, EqualTo class RegisterForm(FlaskForm): username StringField(用户名, validators[ DataRequired(), Length(min3, max20, message用户名长度必须在3-20个字符之间) ]) email EmailField(邮箱, validators[DataRequired(), Email()]) password PasswordField(密码, validators[ DataRequired(), Length(min6, message密码至少6个字符) ]) confirm PasswordField(确认密码, validators[ DataRequired(), EqualTo(password, message两次密码输入不一致) ]) gender SelectField(性别, choices[(male, 男), (female, 女), (other, 其他)]) bio TextAreaField(个人简介) agree BooleanField(同意用户协议, validators[DataRequired()]) submit SubmitField(注册)4. 表单验证器Flask-WTF和WTForms提供了丰富的表单验证功能。内置验证器验证器作用DataRequired()确保字段不为空Email()验证是否为有效的邮箱地址Length(min, max)限制字符串长度范围EqualTo(fieldname)验证是否与另一个字段值相同NumberRange(min, max)限制数值范围URL()验证是否为有效的URLRegexp(regex)使用正则表达式验证IPAddress()验证是否为有效的IP地址UUID()验证是否为有效的UUIDAnyOf(values)验证值是否在指定列表中NoneOf(values)验证值不在指定列表中自定义验证器除了内置验证器还可以在表单类中定义validate_字段名方法实现自定义验证class RegisterForm(FlaskForm): username StringField(用户名, validators[DataRequired()]) email EmailField(邮箱, validators[DataRequired(), Email()]) submit SubmitField(注册) # 自定义验证检查用户名是否包含敏感词 def validate_username(self, field): if admin in field.data.lower(): raise ValidationError(用户名不能包含 admin) # 自定义验证检查邮箱是否已被注册实际场景中需查询数据库 def validate_email(self, field): if field.data testexample.com: raise ValidationError(该邮箱已被注册)5. 显示验证错误在模板中显示字段的验证错误form methodpost {{ form.hidden_tag() }} div {{ form.username.label }}br {{ form.username(size32) }} {% if form.username.errors %} ul stylecolor:red; {% for error in form.username.errors %} li{{ error }}/li {% endfor %} /ul {% endif %} /div div {{ form.email.label }}br {{ form.email(size32) }} {% if form.email.errors %} ul stylecolor:red; {% for error in form.email.errors %} li{{ error }}/li {% endfor %} /ul {% endif %} /div div {{ form.submit() }} /div /form6. 文件上传Flask支持处理文件上传文件通过request.files访问。创建文件上传表单templates/upload.html!DOCTYPE html html head titleUpload File/title /head body form action/upload methodpost enctypemultipart/form-data label forfileFile:/label input typefile idfile namefile br input typesubmit valueUpload /form /body /htmlenctypemultipart/form-data是文件上传必需的编码类型。使用Flask-WTF的FileFieldimport os from flask import Flask, render_template, request from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired, FileAllowed from wtforms import SubmitField from werkzeug.utils import secure_filename app Flask(__name__) app.secret_key secret app.config[UPLOAD_FOLDER] uploads/ class UploadForm(FlaskForm): file FileField(选择文件, validators[ FileRequired(请选择一个文件), FileAllowed([jpg, png, pdf, txt], 只允许上传 jpg, png, pdf, txt 文件) ]) submit SubmitField(上传) app.route(/upload, methods[GET, POST]) def upload(): form UploadForm() if form.validate_on_submit(): file form.file.data filename secure_filename(file.filename) os.makedirs(app.config[UPLOAD_FOLDER], exist_okTrue) file.save(os.path.join(app.config[UPLOAD_FOLDER], filename)) return f文件 {filename} 上传成功 return render_template(upload.html, formform)文件上传验证器验证器作用FileRequired()确保已选择文件FileAllowed([jpg, png])限制允许的文件扩展名7. CSRF保护Flask-WTF自动为表单提供CSRF跨站请求伪造保护。启用CSRF保护app.secret_key your_secret_key # CSRF令牌加密需要模板中添加CSRF令牌form methodpost {{ form.hidden_tag() }} !-- 其他表单字段 -- /formform.hidden_tag()会生成一个隐藏的CSRF令牌字段提交时Flask-WTF会自动验证。全局CSRF保护也可以为所有视图启用CSRF保护包括非WTForms表单from flask_wtf.csrf import CSRFProtect csrf CSRFProtect(app) # 或在应用工厂模式中 # csrf CSRFProtect() # csrf.init_app(app)对于AJAX请求需要将CSRF令牌放在请求头中// 在模板中获取CSRF令牌 const csrfToken {{ csrf_token() }}; fetch(/api/data, { method: POST, headers: { X-CSRFToken: csrfToken, Content-Type: application/json }, body: JSON.stringify(data) });8. 表单处理完整流程对照步骤纯Flask手动方式Flask-WTF方式1. 定义表单写HTML模板Python表单类2. 渲染表单手写HTML{{ form.field }}3. 获取数据request.form.get(name)form.name.data4. 验证数据手写if判断form.validate_on_submit()5. 错误处理手动处理自动收集到form.field.errors6. CSRF保护需手动实现自动处理hidden_tag()小结本章全面讲解了Flask的表单处理。基础方式使用request.form手动获取和验证数据适合简单场景Flask-WTF扩展提供了更完善的方案——通过表单类定义字段和验证器validate_on_submit()自动完成验证模板中form.hidden_tag()自动生成CSRF令牌。内置验证器涵盖DataRequired、Email、Length、EqualTo等常见需求也支持自定义验证方法。文件上传使用FileField配合FileRequired和FileAllowed验证器配合secure_filename确保安全。Flask-WTF是Flask表单处理的标准方案强烈推荐在实际项目中使用。
返回列表