flask 利用flask_wtf擴展 創建web表單
阿新 • • 發佈:2019-03-05
thead .com -c req title ble 不同 ESS imp
在Flask中,為了處理web表單,我們一般使用Flask-WTF擴展,它封裝了WTForms,並且它有驗證表單數據的功能
- 創建語句格式: 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"}
- 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(‘進 度:‘, 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表單