在Web應用中,表單處理是一個基本而常見的任務。Python的WTForms庫通過提供表單的結構、驗證和渲染等功能,簡化了表單的處理流程。與此同時,Flask的擴展Flask-WTF更進一步地整合了WTForms,為開發者提供了更便捷、靈活的表單處理方式。Flask-WTF是建立在WTForms之上... ...
在Web應用中,表單處理是一個基本而常見的任務。Python的WTForms庫通過提供表單的結構、驗證和渲染等功能,簡化了表單的處理流程。與此同時,Flask的擴展Flask-WTF更進一步地整合了WTForms,為開發者提供了更便捷、靈活的表單處理方式。Flask-WTF是建立在WTForms之上的Flask擴展,旨在簡化Web應用中表單處理的流程。它提供了與Flask框架的無縫集成,使得表單的創建、驗證和渲染變得非常容易。通過Flask-WTF,開發者能夠輕鬆地構建具有強大功能和良好用戶體驗的表單頁面。
主要特點:
- 結合WTForms功能: Flask-WTF基於WTForms庫,繼承了WTForms的強大功能,包括表單欄位、驗證器等,為開發者提供了一套完備的表單處理工具。
- Flask集成: 與Flask框架無縫集成,通過簡單的導入和初始化,即可在Flask應用中使用Flask-WTF提供的表單處理功能。
- CSRF保護: Flask-WTF內置了CSRF(Cross-Site Request Forgery)保護機制,幫助開發者防範Web應用中的CSRF攻擊。
- 表單渲染: 提供了方便的表單渲染方法,使得表單的呈現過程更為簡單,開發者可以輕鬆定製表單的外觀。
- 文件上傳支持: 支持文件上傳功能,使得開發者能夠方便地處理包含文件上傳功能的表單。
通過Flask-WTF,開發者能夠以更高效的方式處理Web應用中的表單,減少重覆性工作,提升開發效率。
簡單驗證表單
前臺定義渲染模板,後端對模板渲染,並根據validators
驗證器中的規則對輸入內容進行匹配。
<form method="post">
{{ form.csrf_token }}
<!--可自定義增加顏色-->
<p>{{ form.username.label(style="color:red;") }} : {{form.username}}</p>
<p>{{ form.password.label }} : {{form.password}}</p>
<p>{{ form.repeat_password.label }} : {{form.repeat_password}}</p>
{% for msg in form.repeat_password.errors %}
<p>提示: {{msg}}</p>
{% endfor %}
{{form.submit}}
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo,Length,Regexp
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
# DataRequired 驗證不為空,Length 限制長度, Regexp限制不允許出現弱口令
username = StringField(label=u"登錄賬號", validators=[DataRequired(), Length(min=6, max=18)])
password = PasswordField(label=u"登錄密碼", validators=[DataRequired(), Length(min=6, max=18)])
repeat_password = PasswordField(label=u"確認密碼", validators=[DataRequired(),EqualTo("password", u"兩次密碼不一致")])
submit = SubmitField(label=u"提交")
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
username = form.username.data
password = form.password.data
repeat_password = form.repeat_password.data
print("用戶名: {} --> 密碼: {}".format(username,repeat_password))
return render_template("index.html", form=form)
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
運行後預設構造一個賬號密碼登錄視窗的表單,用戶可以填寫表單並返回給後臺信息,如下圖所示;
表單附加參數
所謂附加參數就是指,渲染器返回頁面是主動對某個組件增加一些CSS屬性,這些屬性起到裝飾作用,通常會使用render_kw
屬性返回CSS。
{% for msg in get_flashed_messages() %}
<p>閃現消息: {{ msg }}</p>
{% endfor %}
<form method="POST" id="form-data">
{{ form.csrf_token }}
{{ form.username.label }} : {{ form.username }}
{{ form.password.label }} : {{ form.password }}
{{ form.submit.label }} {{ form.submit }}
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request,flash
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo,Length,Regexp
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
username = StringField(
# 標簽
label="賬號",
# 驗證器
validators=[
DataRequired('請輸入用戶名')
],
description="賬號",
# 增加附加參數
render_kw={
"class":"form-control",
"placeholder":"請輸入用戶名",
"required":'required'
}
)
password = PasswordField(
label="密碼",
validators=[
DataRequired('請輸入登錄密碼')
],
description="密碼",
render_kw={
"class": "form-control",
"placeholder": "請輸入登錄密碼",
"required": 'required'
}
)
submit = SubmitField(
label="登錄",
render_kw={
"class": "btn",
}
)
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
username = form.username.data
password = form.password.data
print("用戶名: {} 密碼: {}".format(username, password))
if username == "lyshark" and password == "123123":
flash("密碼正確")
else:
flash("密碼錯誤")
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
運行上述代碼,當用戶輸入密碼錯誤後會出現閃現消息,如下圖所示;
地址驗證表單
Flask框架中特殊表單的驗證有很多,常用的表單驗證也就以下這幾種。
<form method="post">
{{ form.csrf_token }}
<p>{{ form.url.label }} : {{form.url}}</p>
<p>{{ form.address_v4.label }} : {{form.address_v4}}</p>
<p>{{ form.address_v6.label }} : {{form.address_v6}}</p>
<p>{{ form.mac.label }} : {{form.mac}}</p>
{{form.submit}}
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import (BooleanField, DecimalField, DateField, DateTimeField, FieldList,
FloatField, FormField, IntegerField, RadioField, SelectField,
SelectMultipleField, StringField,SubmitField,PasswordField)
from wtforms.validators import (DataRequired, data_required, Email, email, EqualTo, equal_to,
IPAddress, ip_address, InputRequired, input_required, Length,
length, NumberRange, number_range, Optional, optional,
Regexp, regexp, URL, url, AnyOf,
any_of, NoneOf, none_of, MacAddress, mac_address, UUID)
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
url = StringField(label=u"驗證網址", validators=[DataRequired(), Length(min=6, max=30),URL()])
address_v4 = StringField(label=u"驗證IPv4", validators=[DataRequired(), Length(max=30), IPAddress()])
address_v6 = StringField(label=u"驗證IPv6", validators=[DataRequired(), Length(max=30), IPAddress(ipv6=True)])
mac = StringField(label=u"驗證MAC地址",validators=[DataRequired(), Length(max=60), MacAddress()])
submit = SubmitField(label=u"提交")
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
url = form.url.data
address_v4 = form.address_v4.data
address_v6 = form.address_v6.data
mac = form.mac.data
print("網址: {} 地址v4: {} 地址v6: {} MAC地址: {}".format(url,address_v4,address_v6,mac))
return render_template("index.html", form=form)
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
網路IP地址的驗證也有相應的表單,如下表單分別可以實現對不同地址的驗證;
特殊表單驗證
WTF表單除去常規表單驗證以外,還可以驗證其他特殊表單,例如驗證郵箱,浮點數,日期時間等。
<form method="post">
{{ form.csrf_token }}
<!--郵箱-->
<p>{{ form.email.label }} --> {{ form.email }}</p>
{% for msg in form.email.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--年齡-->
<p>{{ form.age.label }} --> {{ form.age }}</p>
{% for msg in form.age.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--小數-->
<p>{{ form.height.label }} --> {{ form.height }}</p>
{% for msg in form.height.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--浮點數-->
<p>{{ form.float_.label }} --> {{ form.float_ }}</p>
{% for msg in form.float_.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--段落-->
<p>{{ form.description.label }} --> {{ form.description }}</p>
{% for msg in form.description.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--日期-->
<p>{{ form.local_date.label }} --> {{ form.local_date }}</p>
{% for msg in form.local_date.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--時間-->
<p>{{ form.time_date.label }} --> {{ form.time_date }}</p>
{% for msg in form.time_date.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--日期時間-->
<p>{{ form.datetime_date.label }} --> {{ form.datetime_date }}</p>
{% for msg in form.datetime_date.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
{{form.submit}}
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms.validators import DataRequired,Regexp,DataRequired, Length, Email, EqualTo, NumberRange
from wtforms.fields import (StringField, PasswordField, DateField, BooleanField,DateTimeField,TimeField,
SelectField, SelectMultipleField, TextAreaField,FloatField,HiddenField,
RadioField, IntegerField, DecimalField, SubmitField,
IntegerRangeField)
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
# 安裝 pip install email-validator
email = StringField(label=u"郵箱地址", validators=[Email(message=u"郵箱格式錯誤"),Length(max=32)])
# 整數類型輸入,必須輸入整型數值,範圍在16到70之間
age = IntegerField(label=u"年齡", validators=[NumberRange(min=16, max=70)])
# 小數類型輸入,必須輸入數字數值,顯示時保留兩位小數
height = DecimalField(label=u"小數輸入", places=2)
# 浮點數類型輸入,必須輸入浮點數值
float_ = FloatField(label=u"浮點數輸入")
# Text Area類型 段落輸入框
description = TextAreaField(label=u"段落輸入")
# 日期類型輸入,必須輸入是 "年-月-日" 格式的日期
local_date = DateField(label=u"日期", format='%Y-%m-%d')
# 時間類型輸入,必須輸入是 "時:分:秒" 格式
time_date = TimeField(label=u"時間", format='%H:%M')
# 日期時間類型,必須輸入是 "年-月-日 時:分:秒" 格式
datetime_date = DateTimeField(label=u"日期時間", format='%Y-%m-%d %H:%M:%S')
submit = SubmitField(label=u"提交")
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
email = form.email.data
age = form.age.data
height = form.height.data
float_ = form.float_.data
description = form.description.data
print("郵箱: {} 年齡: {} 小數點: {} 浮點數: {} 段落輸入: {}".format(email,age,height,float_,description))
local_date = form.local_date.data
time_date = form.time_date.data
datetime_date = form.datetime_date.data
print("日期: {} 時間: {} 日期時間: {}".format(local_date,time_date,datetime_date))
return render_template("index.html", form=form)
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
特殊表單的構建,這裡的表單包括瞭如下圖所示的欄位可以使用;
覆選多選表單
覆選框多選框與下拉選擇框三種表單的驗證方式總結。
<form method="post">
{{ form.csrf_token }}
<!--單選框過濾器-->
<p>{{ form.gender.label }} {{ form.gender }}</p>
{% for msg in form.gender.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--下拉框過濾器-->
<p>{{ form.jobs.label }} {{ form.jobs }}</p>
{% for msg in form.jobs.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--多選框過濾器-->
<p>{{ form.hobby.label }} {{ form.hobby }}</p>
{% for msg in form.hobby.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--單選框過濾器-->
<p>{{ form.accept.label }} {{ form.accept }}</p>
{% for msg in form.accept.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
<!--覆選框過濾器-->
<p>{{ form.favor.label }} {{ form.favor }}</p>
{% for msg in form.favor.errors %}
<p>錯誤提示: {{msg}}</p>
{% endfor %}
{{form.submit}}
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import Form,widgets,validators
from wtforms.fields import simple,core
from wtforms.validators import DataRequired,Regexp,DataRequired, Length, Email, EqualTo, NumberRange
from wtforms.fields import (StringField, PasswordField, DateField, BooleanField,DateTimeField,TimeField,
SelectField, SelectMultipleField, TextAreaField,FloatField,HiddenField,
RadioField, IntegerField, DecimalField, SubmitField,
IntegerRangeField)
from wtforms.fields import simple,core
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
# RadioBox單選框,choices里的內容會在ul標簽里,裡面每個項是(值,顯示名)對
gender = RadioField(label=u"性別", choices=[('man', '男'), ('wo', '女')], validators=[DataRequired()])
# Select下拉單選框,choices里的內容會在Option里,裡面每個項是(值,顯示名)對
jobs = SelectField(label=u"工作", choices=[("teacher","老師"),("doctor","醫生"),("engineer","工程師")])
# Select多選框,choices里的內容會在Option里,裡面每個項是(值,顯示名)對
hobby = SelectMultipleField(label=u"興趣", choices=[('swim', '滲透'),('skate', '運維'),('hike', '科學')])
# Checkbox單選框 加上default='checked' 即預設是選上的
accept = BooleanField(label=u"單選框", default='checked', validators=[DataRequired()])
# Select覆選框, 多選框合併選擇,覆選框
favor = SelectMultipleField(
label="特長",
choices=((1, 'Python'), (2, '滲透'), (3, "運維"), (4, "科學")),
coerce=int, default=[1, 2, 4],
option_widget=widgets.CheckboxInput(),
widget=widgets.ListWidget(prefix_label=False)
)
submit = SubmitField(label=u"提交")
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
gender = form.gender.data
jobs = form.jobs.data
hobby = form.hobby.data
accept = form.accept.data
favor = form.favor.data
print("性別: {} 工作: {} 興趣: {} 是否接受: {} 覆選框: {}".format(gender,jobs,hobby,accept,favor))
return render_template("index.html", form=form)
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
選擇菜單包括了單選與多選,如下圖所示的表單均可以構建;
文件上傳表單
文件上傳Flask也提供了預設表單可以使用,如下提供的FileField
即可完成上傳工作。
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
{{ form.attach.label }} {{ form.attach }}
<input type="submit" value="Submit">
</form>
後臺定義MyFlaskForm(FlaskForm)
類用於對登錄表單進行動態渲染。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from werkzeug.utils import secure_filename
from flask_wtf.file import FileField, FileAllowed, FileRequired
app = Flask(__name__)
app.config["SECRET_KEY"] = "d3d3Lmx5c2hhcmsuY29t"
# 定義表單模型類
class MyFlaskForm(FlaskForm):
attach = FileField(label="上傳文件",validators=[
FileRequired(),
FileAllowed(["jpg","png"],"只可上傳圖片")
])
@app.route("/", methods=["GET", "POST"])
def index():
form = MyFlaskForm()
if request.method == "POST":
if form.validate_on_submit():
filename = secure_filename(form.attach.data.filename)
form.attach.data.save('/' + filename)
return 'Upload successfully!'
return render_template("index.html", form=form)
return render_template("index.html", form=form)
if __name__ == '__main__':
app.run(debug=True)
上傳表單時需要註意,啟動的進程必須具備管理員許可權或者是讀寫許可權,否則則會提示許可權拒絕;
文章出處:https://www.cnblogs.com/LyShark/p/17857906.html本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!