整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HTML表單|如何在HTML頁面創建表單的文本域和密碼域?

          TML 表單用于收集不同類型的用戶輸入,它是一個包含表單元素的區域。

          表單元素是允許用戶在表單中輸入內容,比如:文本域(textarea)、下拉列表、單選框(radio-buttons)、復選框(checkboxes)等等。今天我們主要來說說文本域和密碼域這兩個部分,希望對大家學習有所幫助喲!

          本文福利后臺回復【學習】即可獲得Python、HTML等編程學習資料

          HTML 表單

          表單使用表單標簽 <form> 來設置:

          <form>

          First name: <input type="text" name="firstname"><br>

          Last name: <input type="text" name="lastname">

          </form>


          HTML 表單 - 輸入元素

          多數情況下被用到的表單標簽是輸入標簽(<input>)。輸入類型是由類型屬性(type)定義的。

          如何在 HTML 頁面創建文本域?

          用戶可以在文本域中寫入文本,參考代碼如下:

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>菜鳥教程(runoob.com)</title>

          </head>

          <body>

          <form action="">

          First name: <input type="text" name="firstname"><br>

          Last name: <input type="text" name="lastname">

          </form>

          <p><b>注意:</b> 表單本身是不可見的。并且注意一個文本字段的默認寬度是20個字符。</p>

          </body>

          </html>

          運行結果為

          如何創建 HTML 的密碼域?

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>菜鳥教程(runoob.com)</title>

          </head>

          <body>

          <form action="">

          Username: <input type="text" name="user"><br>

          Password: <input type="password" name="password">

          </form>

          <p><b>注意:</b> 密碼字段中的字符是隱藏的(顯示為星號或圓圈)。</p>

          </body>

          </html>

          運行結果如下


          戳了解更多免費領取HTML試聽課~

          在開篇

          什么是表單呢?當前端想要提交數據給后端,怎么搞?那么在前端開發中,表單是常用的手段,比如常見的場景有:登錄框、賬號注冊頁、主機信息錄入CMDB等等場景都是需要表單。那么在本篇中,筆者除了講一些基本的知識點,還會再結合后端的方式來演示如何接收表單提交的數據。希望這些小小的演示可以起到拋磚引玉的效果。

          盤點HTML表單基礎

          1. from元素

          構建表單,主要是通過from元素,我們先來一個最簡單的小栗子,看下面代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>主機信息錄入CMDB</h3>
                  <form>
                      <label for="hostname">主機名:</label><br>
                      <input type="text" id="hostname" name="hostname"><br>
                      <label for="ipaddr">IP地址:</label><br>
                      <input type="text" id="ipaddr" name="ipaddr"><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          效果如下圖:

          通上面的小栗子可以知道,form表單的主要通途是用于收集用戶的輸入。在from表單里面,還包含著各種不同類型的input元素,比如我們上面小栗子中用到的文本(text)、提交按鈕(submit)。

          input元素是表單里最重要的元素,它有很多type屬性,下面我們來總結下:

          類型描述text文本輸入radio單選按鈕checkbox提交按鈕submit提交按鈕button可單擊按鈕

          在上面小栗子中,除了input元素之外,不知道大家注意label元素沒有。label元素的主要用途是為input元素定義標簽,且用for屬性和input元素的id屬性進行綁定呢。

          2. 單選按鈕

          什么是單選按鈕?就是在多個選項中,你只能選其中1個,不能多選。下面我們看個小栗子,看下面代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>問答題1(單選):某站長,工作經驗不足1年,僅從互聯網收集學習資料制定學習路線售賣盈利,從道德層面角度分析是否有問題?</h3>
                  <form>
                      <input type="radio" id="i1" name="problem" value="yes">
                      <label for="i1">有</label>
                      <input type="radio" id="i2" name="problem" value="no">
                      <label for="i2">沒有</label>
                      <input type="radio" id="i3" name="problem" value="not_clear">
                      <label for="i3">不清楚</label>
                  </form>
                  <h3>問答題2(單選):實際工作經驗不足1年的人員折騰的學習資料您覺得是否對你有幫助?</h3>
                  <form>
                      <input type="radio" id="w1" name="problem" value="yes">
                      <label for="w1">有</label>
                      <input type="radio" id="w2" name="problem" value="no">
                      <label for="w2">沒有</label>
                      <input type="radio" id="w3" name="problem" value="not_clear">
                      <label for="w3">不清楚</label>
                  </form>
              </body>
          </html>
          

          效果如下圖:

          上面的小栗子中,出了兩道問答題,均為單選題。那么,類似的需求都是可以使用輸入類型為radio來實現需要使用單選按鈕的場景。

          3. 復選框

          什么是復選框?復選框就是可以選擇多個選項,當需要多選的時候,使用復選框輸入類型就對了。看下面代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>問答題1(單選):某站長,工作經驗不足1年,僅從互聯網收集學習資料制定學習路線售賣盈利,從道德層面角度分析是否有問題?</h3>
                  <form>
                      <input type="checkbox" id="i1" name="problem" value="yes">
                      <label for="i1">有</label>
                      <input type="checkbox" id="i2" name="problem" value="no">
                      <label for="i2">沒有</label>
                      <input type="checkbox" id="i3" name="problem" value="not_clear">
                      <label for="i3">不清楚</label><br>
                      <input type="submit" value="提交">
                  </form>
                  <h3>問答題2(單選):實際工作經驗不足1年的人員折騰的學習資料您覺得是否對你有幫助?</h3>
                  <form>
                      <input type="checkbox" id="w1" name="problem" value="yes">
                      <label for="w1">有</label>
                      <input type="checkbox" id="w2" name="problem" value="no">
                      <label for="w2">沒有</label>
                      <input type="checkbox" id="w3" name="problem" value="not_clear">
                      <label for="w3">不清楚</label><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          效果如下圖:

          上面的小栗子中,實現復選框的輸入類型是checkbox,這個是重點哦!

          4. 提交按鈕

          當有數據要提交給后端的時候怎么搞?如果后端是API服務,可以給它提交json。如果是前端頁面,就需要通過構建表單來獲取用戶的輸入。基于表單提交數據給后端,怎么提交?需要一個可以點擊的提交按鈕,那這個按鈕怎么來?先看下面代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>主機信息</h3>
                  <form>
                      <label for="ipaddr">IP地址</label>
                      <input type="text" id="ipaddr" name="ip"><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          效果如下圖:

          輸入類型為submit,說明它就是提交按鈕,注意上面代碼type="submit"了嗎?

          HTML表單重要屬性

          1. Action屬性

          在之前的例子中,前端表單需要將數據提交給后端,除了需要一個提交按鈕外,還需要action屬性。當點擊提交按鈕后,表單的數據該發到后端的哪個url進行處理,就是定義在action屬性中。接下來,我們結合前端和后端直接來個小實戰,后端代碼用Python的Flask框架。

          前端代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>主機信息</h3>
                  <form action="http://192.168.11.10:8088/ttropsstack" target="_blank">
                      <label for="ipaddr">IP地址</label>
                      <input type="text" id="ipaddr" name="ip"><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          后端代碼:

          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=["GET", "POST"])
          def ttropsstack():
              args = request.args
              print 'ip addr is: %s' % args.get('ip')
              return 'ok'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          前端和后端的代碼寫完后,我們接下來看看效果

          輸入IP地址后,點擊提交

          這個ok是后端返回的

          后端接收到數據后,啥也沒做,只是做了簡單打印

          這個小栗子很簡單,通過這個小栗子,是不是對action屬性的用法有了進一步的理解呢?

          2. Method屬性

          method屬性的用途是指定提交數據的http方法,通常有2個,get和post。接下來我們在上個小栗子的基礎上做個小改造,看下面代碼

          前端代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>主機信息</h3>
                  <form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="get">
                      <label for="ipaddr">IP地址</label>
                      <input type="text" id="ipaddr" name="ip"><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          后端代碼:

          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=["POST"])
          def ttropsstack():
              args = request.args
              print 'ip addr is: %s' % args.get('ip')
              return 'ok'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          當前端輸入數據后,提交表單時,直接告訴你這是不允許的方法

          在這個例子中,是因為前端的表單了指定了method為get請求,而后端接收數據的method規定了需要post請求,故所以出現這個問題。

          下面我們改造一下后端代碼:

          # coding: utf8
          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=['GET','POST'])
          def ttropsstack():
              if request.method == 'POST':
                  print request.get_data(as_text=True)
                  return 'ok'
              else:
                  return '提交數據需要post請求'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          前端表單中的method還是保持get請求,再次提交,后端的返回如下:

          看到了嗎?后端判斷前端過來的請求是get還是post,很顯然,前端過來的請求是get,并且返回了非常友好的提示。

          接下來我們繼續改造一下前端的代碼,將請求修改為post,代碼如下:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <h3>主機信息</h3>
                  <form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
                      <label for="ipaddr">IP地址</label>
                      <input type="text" id="ipaddr" name="ip"><br>
                      <input type="submit" value="提交">
                  </form>
              </body>
          </html>
          

          后端代碼也稍微改造一下,改變接收前端數據的方法

          # coding: utf8
          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=['GET','POST'])
          def ttropsstack():
              if request.method == 'POST':
                  a = request.form
                  print a.get('ip')
                  print type(a)
                  return 'ok'
              else:
                  return '提交數據需要post請求'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          輸入IP地址,并點擊提交

          提交后,后端給前端返回了ok

          接下來看下后端,后端啥也沒做,就獲取到表單的數據,然后打印了數據,并且打印了下數據類型

          好了,關于前端的action屬性和Method屬性就講到這里了。為了講解action和method,還結合了后端的一丟丟知識,前端和后端的知識點以后都會慢慢講到哈!

          HTML表單常用元素

          1. 下拉列表

          先來個前端代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
                      <label for="opslist">運維開發應掌握的技能:</label>
                      <select id="opslist" name="opslist">
                          <option value="python">Python語言</option>
                          <option value="go">Go語言</option>
                          <option value="shell">Shell語言</option>
                          <option value="database">數據庫</option>
                          <option value="frontend">前端</option>
                          <option value="linux">Linux</option>
                          <option value="network">網絡</option>
                          <option value="storage">存儲</option>
                      </select>
                      <input type="submit">
                  </form>
              </body>
          </html>
          

          后端代碼:

          # coding: utf8
          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=['GET','POST'])
          def ttropsstack():
              if request.method == 'POST':
                  a = request.form
                  print a.get('opslist')
                  return 'ok'
              else:
                  return '提交數據需要post請求'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          在下拉框中選擇“Go語言”,并提交

          后端啥也沒干,就只做了打印

          2. 允許多選

          前端代碼:

          <!DOCTYPE html>
          <html lang="zh">
              <head>
                  <meta charset="UTF-8">
                  <title>彩虹運維技術棧社區主頁</title>
              </head>
              <body>
                  <h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
                  <form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
                      <label for="opslist">運維開發應掌握的技能:</label>
                      <select id="opslist" name="opslist" size="6" multiple>
                          <option value="python">Python語言</option>
                          <option value="go">Go語言</option>
                          <option value="shell">Shell語言</option>
                          <option value="database">數據庫</option>
                          <option value="frontend">前端</option>
                          <option value="linux">Linux</option>
                          <option value="network">網絡</option>
                          <option value="storage">存儲</option>
                      </select>
                      <input type="submit">
                  </form>
              </body>
          </html>
          

          上述前端代碼中,是使用multiple屬性來實現選擇多個值。

          后端代碼的打印方式稍微做了些許調整:

          # coding: utf8
          from flask import Flask, request
          
          webapp = Flask(__name__)
          
          @webapp.route('/ttropsstack', methods=['GET','POST'])
          def ttropsstack():
              if request.method == 'POST':
                  data = request.get_data()
                  print data
                  return 'ok'
              else:
                  return '提交數據需要post請求'
          
          if __name__ == '__main__':
          
              webapp.run(host="0.0.0.0", port=8088, debug=True)
          

          按住ctrl或者shift鍵可進行多選

          后端打印的效果圖下圖:

          寫在最后

          關于表單基礎知識點的講解就這么愉快的結束了,關于更多表單的元素、輸入屬性、輸入類型可自行查閱和實戰,筆者因時間有限就不一一演示。感謝您的閱讀,望多多關注我們、點贊、轉發!

          本文轉載于(喜歡的盆友關注我們):https://mp.weixin.qq.com/s/L-Msv39JrF7AzRx4K1OLjA

          一章節我們通過在html中直接編寫表單的方式進行數據傳遞,并且在視圖中對前端傳遞的數據進行了簡單的認證,但是如果把驗證數據的代碼與邏輯混合在一起,將使得視圖的代碼不夠清晰,并且難以維護,稍加疏忽就會產生驗證漏洞,如果細心的同學其實可以發現,在之前的登錄注冊中我們一直沒有對空表單進行驗證,當然這是我故意為之,但如果在生產環境,這將是一個災難的開始,所以,在編程中無論是前端還是后端都要求要對數據進行驗證,作為后端,更要保持一種永遠不相信前端傳遞數據的態度去做數據校驗。

          本章節我們將使用Flask官方推薦的Flask-WTF擴展來重構我們的登錄注冊表單!

          關于Flask-WTF

          Flask-WTF是Flask 和 WTForms 的簡單集成,包括 CSRF、文件上傳和 reCAPTCHA。

          • 安裝Flask-WTF:
          pip install Flask-WTF

          創建登錄注冊表單類

          app/auth/目錄下新建一個forms.py的文件,所有的表單驗證代碼都放到這個文件當中!

          構建登錄表單

          from flask_wtf import FlaskForm
          from wtforms import StringField, PasswordField
          from wtforms.validators import DataRequired, Length, ValidationError, EqualTo
          from werkzeug.security import check_password_hash
          from .models import User
          
          class LoginForm(FlaskForm):
              # 登錄表單
          
              def qs_username(username):
                  # 對該字段進行在傳遞之前處理
                  u = f'{username}123456'
                  print(u)
                  return username
          
              username = StringField('username', validators=[
                  DataRequired(message="不能為空"), 
                  Length(max=32, message="不符合字數要求!")
                  ], filters=(qs_username,))
              password = PasswordField('password', validators=[
                  DataRequired(message="不能為空"),
                  Length(max=32, message="不符合字數要求!")
                  ])
          
              def validate_username(form, field):
                  user = User.query.filter_by(username=field.data).first()
                  if user is None:
                      error = '該用戶不存在!'
                      raise ValidationError(error)
                  elif not check_password_hash(user.password, form.password.data):
                      raise ValidationError('密碼不正確')

          代碼詳解:

          class LoginForm(FlaskForm): 創建了一個登錄表單類,繼承了FlaskForm類

          StringField, PasswordField

          這些都是wtforms內置的字段,負責呈現和數據轉換。

          官方文檔:https://wtforms.readthedocs.io/en/3.0.x/fields/

          他繼承自Filed的基類,其中有一些比較重要的參數我們大概在這里理解一下!

          第一個字符串其實是該類的label參數,字段的標簽,也就是轉換到html中的label!

          validators傳入對該字段的一些驗證器,在提交數據之前對數據進行驗證!

          filters這個參數比較特殊,官方文檔并沒有對其詳細說明,只說是篩選器,其實怎么說就是在額外的方法中對該字段的值提前處理過濾,元組中的每個值都是一個回調函數,函數不需要傳入括號,但這個回調函數默認有一個參數,這個參數就是本身該字段的值,所以在定義該函數時就必須傳入一個參數!例如:我們定義username之前定義的這個方法!

          def qs_username(username):
              # 對該字段進行在傳遞之前處理
              u = f'{username}123456'
              print(u)
              return username

          備注:必須返回處理后的這個參數,否則會觸發DataRequired驗證器,后端獲取不到該表單的值!

          • DataRequired, Length 這是內置的驗證器,第一個是驗證字段是否為空,第二個Length是驗證輸入長度,當然內置的還有很多,這里就不一一列舉,具體我們可參考文檔!

          官方文檔: https://wtforms.readthedocs.io/en/3.0.x/validators/#custom-validators

          自定義驗證用戶名和密碼

          在之前的視圖函數中我們對用戶名和密碼都做了校驗,現在我們需要把驗證的代碼全部移動到表單類中,代碼如下:

          def validate_username(form, field):
              user = User.query.filter_by(username=field.data).first()
              if user is None:
                  error = '該用戶不存在!'
                  raise ValidationError(error)
              elif not check_password_hash(user.password, form.password.data):
                  raise ValidationError('密碼不正確')
          • validate_username(form, field)

          這個函數的寫法是固定的validate_{filed},validate_后邊的filed是指你需要驗證的某個字段名,比如我們這個驗證,他主要就是對username字段進行驗證,這個函數中參數的filed就是這個字段,通過field.data就可以獲取到usernam的值。form參數則指代的是整個表單,可以用form.{filed}.data的方式獲取表單類中某個具體字段的值!

          構建注冊表單

          當了解了登錄表單后,我們完全就可以參照登錄表單去實現注冊表單,代碼如下:

          路徑:app/auth/forms.py

          class RegisterForm(FlaskForm):
              # 注冊表單
              username = StringField('username', validators=[
                  DataRequired(message="不能為空"), 
                  Length(min=2, max=32, message="超過限制字數!")
                  ])
              password = PasswordField('password', validators=[
                  DataRequired(message="不能為空"),
                  Length(min=2, max=32, message="超過限制字數!"),
                  EqualTo('password1', message='兩次密碼輸入不一致!')
                  ])
              password1 = PasswordField('password1')
          
              def validate_username(form, field):
                  user = User.query.filter_by(username=field.data).first()
                  if user is not None:
                      error = '該用戶名稱已存在!'
                      raise ValidationError(error)

          這里唯一需要注意的是兩次密碼是否輸入一致,我們用了一個內置的驗證器EqualTo,使用方式可完全參照代碼,他會自動校驗password和password1輸入的值是否一致!

          重構登錄和注冊視圖

          • 路徑:app/auth/views/auth.py
          from ..forms import LoginForm, RegisterForm
          
          @bp.route('/login', methods=['GET', 'POST'])
          def login():
              # 登錄視圖
              # form = LoginForm(meta={'csrf': False}) # 禁用csrf
              form = LoginForm()
              if form.validate_on_submit():
                  user = auth.User.query.filter_by(username=form.username.data).first()
                  session.clear()
                  session['user_id'] = user.id
                  return redirect(url_for('index'))
              return render_template('login.html', form=form)
          
          
          @bp.route('/register', methods=['GET', 'POST'])
          def register():
              # 注冊視圖
              form = RegisterForm()
              if form.validate_on_submit():
                  user = auth.User(username=form.username.data, password=generate_password_hash(form.password.data))
                  db.session.add(user)
                  db.session.commit()
                  session.clear()
                  session['user_id'] = user.id
                  return redirect(url_for('index'))
              return render_template('register.html', form=form)

          1、首先從forms.py中引入了我們定義的登錄(LoginForm)和注冊(RegisterForm)表單類!

          2、form = RegisterForm() 實例化表單類

          3、if form.validate_on_submit(): 驗證前端傳遞的數據是否有效,并且會自動判斷是POST請求還是GET請求!

          4、 數據驗證通過則進入之后的邏輯,未驗證通過則返回我們在表單類中傳入的驗證提示!

          模板中調用驗證信息

          我們以調用username字段的驗證提示為例,在模板中加入這段代碼即可獲得錯誤提示!

          <!-- 表單驗證 -->
          {% if form.username.errors %}
          <b-message type="is-danger">
              <ul class="errors">
                  {% for error in form.username.errors %}
                      <li>{{ error }}</li>
                  {% endfor %}
              </ul>
          </b-message>
          {% endif %}

          重構登錄注冊html模板

          路徑:app/auth/templates/login.html 以登陸表單為例,代碼如下:

          {% block auth_form %}
              <form action="" method="post" style="margin-top: 40%;" class="box">
                  <div class=" has-text-centered mb-3">
                    <p class=" subtitle">登錄</p>
                    <h1 class="title">FlaskBlog</h1>
                  </div>
                  {{ form.csrf_token }}
                  <!-- 消息閃現 -->
                  {% with messages = get_flashed_messages() %}
                  <b-message type="is-danger">
                    {% if messages %}
                    <ul class=flashes>
                      {% for message in messages %}
                      <li>{{ message }}</li>
                      {% endfor %}
                    </ul>
                    {% endif %}
                  </b-message>
                  {% endwith %}
          
                  <!-- 表單驗證 -->
                  {% if form.username.errors %}
                  <b-message type="is-danger">
                    <ul class="errors">
                      {% for error in form.username.errors %}
                      <li>{{ error }}</li>
                      {% endfor %}
                    </ul>
                  </b-message>
                  {% endif %}
          
                  <div class="field">
                    <p class="control has-icons-left has-icons-right">
                      {{ form.username(class='input', placeholder='Username') }}
                      <span class="icon is-small is-left">
                        <i class="fas fa-envelope"></i>
                      </span>
                      <span class="icon is-small is-right">
                        <i class="fas fa-check"></i>
                      </span>
                    </p>
                  </div>
                  <div class="field">
                    <p class="control has-icons-left">
                      {{ form.password(class='input', placeholder='Password') }}
                      <span class="icon is-small is-left">
                        <i class="fas fa-lock"></i>
                      </span>
                    </p>
                  </div>
                  <div class="field">
                    <p class="control">
                      <input class="button is-success is-fullwidth" type="submit" value="Login">
                    </p>
                  </div>
                </form>
              {% endblock auth_form %}

          {{ form.csrf_token }} 隱式的創建一個csrftoken的表單

          {{ form.username(class='input', placeholder='Username') }} 這樣就可以直接獲得一個表單html并自動渲染,向該表單增加書香的方式就是像代碼中這樣傳入參數和值即可,當然也可以提前在表單類中定義!

          剩下的注冊表單,就當是給大家留作的一個作業,大家自行去參照登錄表單完善重構一下,加油哦!我相信你可以!

          到這里我們的表單驗證就大概了解了,之后的章節就是基本的增刪改查以及表單驗證,都是基于我們這些章節學習的知識點,所以之后的章節就不會過多的去講解每行代碼的意思,重心放在邏輯的展示上,如果基礎較差的同學,到這里,可以去反復的把前邊所有章節的內容去練習,寫代碼其實就是寫的多了就會了,也就理解了,練習 練習 再練習!


          主站蜘蛛池模板: 无码国产精品一区二区免费| 国产成人精品一区二三区在线观看 | 亚洲高清美女一区二区三区| 无码国产伦一区二区三区视频| 日韩AV无码久久一区二区| 中文字幕一区在线播放| 国产SUV精品一区二区88| 无码人妻少妇色欲AV一区二区| 美女视频免费看一区二区| 亚洲AV无码一区二区三区在线| 视频一区二区在线播放| 成人一区专区在线观看| 3D动漫精品啪啪一区二区下载| 人妻久久久一区二区三区| 日本一区二区不卡视频| 成人无码AV一区二区| 高清国产精品人妻一区二区| 无码日韩人妻AV一区免费l| 日韩美女视频一区| 国产婷婷色一区二区三区深爱网| 无码囯产精品一区二区免费 | 亚洲一区二区三区在线观看蜜桃 | 精品亚洲AV无码一区二区三区| 国产天堂一区二区综合| 日韩A无码AV一区二区三区| 国产精品亚洲一区二区无码| 国产精品一区二区资源| 亚洲一区二区三区国产精品| 精品一区二区三区色花堂 | 久久久精品人妻一区二区三区蜜桃| 精品视频一区二区三区免费| 青青青国产精品一区二区| 天堂va在线高清一区| 日本一区二区三区日本免费| 国产免费伦精品一区二区三区| 中文字幕在线精品视频入口一区| 无码精品视频一区二区三区 | 久久国产精品无码一区二区三区| 97久久精品无码一区二区| 国产精品盗摄一区二区在线| 精品国产免费一区二区三区|