1. 程式人生 > >flask 利用flask_wtf擴展 創建web表單

flask 利用flask_wtf擴展 創建web表單

thead .com -c req title ble 不同 ESS imp

在Flask中,為了處理web表單,我們一般使用Flask-WTF擴展,它封裝了WTForms,並且它有驗證表單數據的功能

  1. 創建語句格式: startTime = DateTimeField(‘計劃開始時間‘, validators=[DataRequired(‘不可為空‘),EqualTo(‘nowTime‘,message=‘兩次事件必須一致‘)],format=‘%Y/%m/%d %H:%M:%S‘ render_kw={‘placeholder‘:‘2018-06-03 00:00:00‘, ‘id‘: ‘rz1‘,‘autocomplete‘: "off"}
  2. html效果:

    <label>計劃開始時間</label>

    <input autocomplete="off" class="form-control" id="rz1" name="startTime" placeholder="2018-06-03 00:00:00" required="" type="text" value="">  

  3. 頁面展示效果:

    技術分享圖片

解析:

  • DataTimeField是從wtforms包導入的字段類 from wtfms import SelectField, StringField, SubmitField, TextField, DateTimeField, FileField。。。
  • ‘計劃開始時間‘是input標簽的lable
  • validators是驗證器,驗證輸入值的合法性,以列表的形式封裝各種驗證函數,驗證函數由wtforms.validators導入:from wtforms.validators import DataRequired
  • format指定展示格式
  • render_kw以字典的形式存放input標簽的各種屬性

form.py文件在項目中的位置:與邏輯層同級,即與view.py同級,以便於不同的功能塊放不同的form表單

項目效果: 三個文件依次是創建藍圖 創建form表單 邏輯(視圖)函數

                     技術分享圖片

創建表單部分代碼案例:

技術分享圖片
 1 from flask_wtf import Form
 2 from wtforms import SelectField, StringField, SubmitField, TextField, DateTimeField, FileField, SelectMultipleField, TextAreaField, HiddenField
 3 from wtforms.validators import DataRequired
 4 
 5 
 6 class TaskinfoAdd(Form):
 7     taskName = StringField(任務名稱:, [DataRequired(任務名稱不能為空)], render_kw={placeholder: 任務名稱, autocomplete: off})
 8     taskInfo = TextAreaField(詳情描述:, render_kw={placeholder: 任務描述..., autocomplete: off})
 9     urgentId = SelectField(緊急程度:, validators=[DataRequired(請選擇緊急程度)], coerce=int, render_kw={style: width:110px})
10     resPeople = StringField(責任人:, [DataRequired(責任人不能為空)], render_kw={class: res-people, placeholder: 責任人, style: width:110px, data-toggle:"modal", data-target:"#myModal2"})
11     exePeople = StringField(參與人(多選):, render_kw={class: exe-people, placeholder: 參與人(多選), style: width:300px})
12     sharePeople = StringField(共享人(多選):, render_kw={placeholder: 共享人(多選), style: width:300px})
13     startTime = DateTimeField(計劃開始時間:, [DataRequired(開始時間不能為空)], format=%Y-%m-%d %H:%M:%S, render_kw={placeholder:2018-06-03 00:00:00, id: rz1, class: form-control calendar-control, autocomplete: "off"})
14     endTime = DateTimeField(計劃完成時間:, [DataRequired(完成時間不能為空)], format=%Y-%m-%d %H:%M:%S, render_kw={placeholder:2019-06-06 00:00:00, id: rz2, class: form-control calendar-control, autocomplete: off})
15     workTime = StringField(計劃工時(分鐘):, [DataRequired(工時不能為空)], render_kw={placeholder: 60})
16 
17     loadFile = FileField(附件, render_kw={multiple: multiple})
18     submit = SubmitField(保存)
19 
20 
21 class TaskinfoEdit(Form):
22     taskName = StringField(任務名稱:, [DataRequired(任務名稱不能為空)])
23     taskInfo = TextAreaField(詳情描述:, render_kw={placeholder: 任務描述..., autocomplete: off})
24     urgentId = SelectField(緊急程度:, validators=[DataRequired(不可為空)], coerce=int, render_kw={style: width:135px; display:inline-block})
25     resPeople = StringField(責任人:, [DataRequired(責任人不能為空)], render_kw={style: width:150px; display:inline-block})
26     advanceId = SelectField(進&nbsp;&nbsp;&nbsp;度:, coerce=int, render_kw={placehoder: 50%, style: width:153px; display:inline-block})
27     workTime = StringField(計劃工時(分鐘):, [DataRequired(工時不能為空)], render_kw={style: width:100px; display: inline-block})
28     exePeople = StringField(參與人:, render_kw={style: width:220px; display: inline-block})
29     sharePeopleTo = StringField(共享人:, render_kw={style: width:220px; display: inline-block})
30 
31     loadFile = FileField(上傳附件:, render_kw={multiple: multiple})
32     download = StringField(下載附件:, render_kw={placehoder: 無附件, style: background: white; height:23px; display: inline-block}, id=download)
33     reason = StringField(超期原因:, render_kw={placeholder: 超期原因..., autocomplete: off})
34     submit = SubmitField(提交)
form.py

flask接收後端處理:

技術分享圖片
 1 @task_mgm.route(/taskinfo_add, methods=[GET, POST])
 2 @login_required
 3 def taskinfo_add_fun():
 4     form1 = TaskinfoAdd()
 5     form1.urgentId.choices = [(urgences.id, urgences.urgentName) for urgences in Urgence.query.all()]
 6     if form1.validate_on_submit():
 7         task = MgmTask(taskName=form1.taskName.data, urgentId=form1.urgentId.data, resPeople=form1.resPeople.data,
 8                     exePeople=form1.exePeople.data, sharePeopleTo=form1.sharePeople.data, startTime=form1.startTime.data,
 9                     endTime=form1.endTime.data, workTime=form1.workTime.data, taskInfo=form1.taskInfo.data,
10                     createPeople=current_user.name)
11         # 替換漢語逗號
12         task.sharePeopleTo.replace(, ,)
13         task.resPeople.replace(, ,)
14         task.exePeople.replace(, ,)
15         #  保存上傳的文檔
16         upload(form1, task)
17         try:
18             db.session.add(task)
19             db.session.commit()
20         except Exception as e:
21             logging.error(e)
22         return redirect(url_for(task_mgm.taskinfo_add_fun))
23     return render_template(/task_mgm/taskinfo_mine.html, form1=form1, name=current_user.name, grade=current_user.grade)
24 
25 
26 # 編輯任務
27 @task_mgm.route(/taskinfo_editID=<int:num>, methods=[GET, POST])
28 @login_required
29 def taskinfo_edit_fun(num):
30     task = MgmTask.query.get(num)
31     pageType = request.values.get(pageType)
32     formEdit = TaskinfoEdit(obj=task)
33     formEdit.urgentId.choices = [(urgences.id, urgences.urgentName) for urgences in Urgence.query.all()]
34     formEdit.advanceId.choices = [(advances.id, advances.name) for advances in Advance.query.all()]
35     if task.fileName:
36         formEdit.download.data = task.fileName
37     if formEdit.validate_on_submit():
38         formEdit.populate_obj(task)  # 重新填充表單
39         if formEdit.advanceId.data == 5:
40             task.finishTime = datetime.now()
41         upload(formEdit, task)
42         try:
43             db.session.add(task)
44             db.session.commit()
45         except Exception as e:
46             logging.error(e)
47         
48     page = request.args.get(page, 1, type=int)
49     pagination = Comment.query.filter(Comment.taskId == num).order_by(Comment.createTime.desc()).paginate(
50             page, per_page=225, error_out=False)
51     comments = pagination.items
52     return render_template(/task_mgm/taskinfo_edit.html, formEdit=formEdit, header=編輯任務, comments=comments, pagination=pagination, pageType=pageType, name=current_user.name, grade=current_user.grade)
view.py

html前端可以繼承bootstrap的wtf.html 也可以直接寫:

  • 繼承:    
1 {% import "bootstrap/wtf.html" as wtf %}
2 
3 <div class="modal-body" style="margin-top: 20px">{{ wtf.quick_form(form1, form_type=horizontal, horizontal_columns=(md, 3, 8)) }}
5   <button type="button" class="btn btn-default" data-dismiss="modal"
6    style="position:relative; margin-left: 460px; bottom:49px;">關閉
7   </button>
8   </div>
  • 不繼承
1 <form method="post">
2     {#設置csrf_token#}
3     {{ form.csrf_token() }}
4     {{ form.username.label }}{{ form.username }}<br>
5     {{ form.password.label }}{{ form.password }}<br>
6     {{ form.password2.label }}{{ form.password2 }}<br>
7     ...
8     {{ form.input }}<br>
9 </form>

WTForms支持的HTML標準字段:

字段對象說明
StringField 文本字段
TextAreaField 多行文本字段
PasswordField 密碼文本字段
HiddenField 隱藏文件字段
DateField 文本字段,值為 datetime.date 文本格式
DateTimeField 文本字段,值為 datetime.datetime 文本格式
IntegerField 文本字段,值為整數
DecimalField 文本字段,值為decimal.Decimal
FloatField 文本字段,值為浮點數
BooleanField 復選框,值為True 和 False
RadioField 一組單選框
SelectField 下拉列表
SelectMutipleField 下拉列表,可選擇多個值
FileField 文件上傳字段
SubmitField 表單提交按鈕
FormField 把表單作為字段嵌入另一個表單
FieldList 一組指定類型的字段

WTForms常用驗證函數:

驗證函數說明
DataRequired 確保字段中有數據
EqualTo 比較兩個字段的值,常用於比較兩次密碼輸入
Length 驗證輸入的字符串長度
NumberRange 驗證輸入的值在數字範圍內
URL 驗證URL
AnyOf 驗證輸入值在可選列表中
NoneOf 驗證輸入值不在可選列表中

提示:

使用Flask-WTF需要配置參數SECRET_KEY。

CSRF_ENABLED是為了CSRF(跨站請求偽造)保護。 SECRET_KEY用來生成加密令牌,當CSRF激活的時候,該設置會根據設置的密匙生成加密令牌

flask 利用flask_wtf擴展 創建web表單