表單支援

在 Web 開發中對於這樣的一個流程可能很眼熟:

  • 開啟一個網頁顯示出表單。

  • 使用者填寫並提交了表單。

  • 如果使用者提交了一些無效的資訊,或者可能漏掉了一個必填項,表單將會連同使用者的資料和錯誤問題的描述資訊回傳。

  • 使用者再次填寫,繼續上一步過程,直到提交了一個有效的表單。

在接收端,指令碼必須:

  • 檢查使用者提交的表單資料。

  • 驗證資料是否為正確的型別,合適的標準。例如,如果一個使用者名稱被提交,它必須被驗證是否只包含了允許的字元。它必須有一個最小長度,不能超過最大長度。使用者名稱不能與已存在的他人使用者名稱重複,甚至是一個保留字等。

  • 過濾資料並清理不安全字元,保證邏輯處理中接收的資料是安全的。

  • 如果需要,預格式化資料(資料需要清除空白或者經過 HTML 編碼等等。)

  • 準備好資料,插入資料庫。

儘管上面的過程並不是很複雜,但是通常情況下需要編寫很多程式碼,而且為了顯示錯誤資訊,在網頁中經常要使用多種不同的控制結構。建立表單驗證雖簡單,實施起來實在枯燥無味。

表單和驗證

對於開發者來說,一般開發過程都是相當複雜,而且大多是在重複一樣的工作。假設一個場景專案中忽然需要增加一個表單資料,那麼區域性程式碼的整個流程都需要修改。我們知道 Go 裡面 struct 是常用的一個數據結構,因此 beego 的 form 採用了 struct 來處理表單資訊。

首先定義一個開發 Web 應用時相對應的 struct,一個欄位對應一個 form 元素,透過 struct 的 tag 來定義相應的元素資訊和驗證資訊,如下所示:

type User struct{
    Username     string     `form:text,valid:required`
    Nickname     string     `form:text,valid:required`
    Age            int     `form:text,valid:required|numeric`
    Email         string     `form:text,valid:required|valid_email`
    Introduce     string     `form:textarea`
}

定義好 struct 之後接下來在 controller 中這樣操作

func (this *AddController) Get() {
    this.Data["form"] = beego.Form(&User{})
    this.Layout = "admin/layout.html"
    this.TplNames = "admin/add.tpl"
}

在範本中這樣顯示錶單

<h1>New Blog Post</h1>
<form action="" method="post">
{{.form.render()}}
</form>

上面我們定義好了整個的第一步,從 struct 到顯示錶單的過程,接下來就是使用者填寫資訊,伺服器端接收資料然後驗證,最後插入資料庫。

func (this *AddController) Post() {
    var user User
    form := this.GetInput(&user)
    if !form.Validates() {
        return
    }
    models.UserInsert(&user)
    this.Ctx.Redirect(302, "/admin/index")
}

表單型別

以下列表列出來了對應的 form 元素資訊:

名稱

參數

功能描述

text

No

textbox 輸入框

button

No

按鈕

checkbox

No

多選擇框

dropdown

No

下拉選擇框

file

No

檔案上傳

hidden

No

隱藏元素

password

No

密碼輸入框

radio

No

單選框

textarea

No

文字輸入框

表單驗證

以下列表將列出可被使用的原生規則

規則

參數

描述

舉例

required

No

如果元素為空,則回傳 FALSE

matches

Yes

如果表單元素的值與參數中對應的表單欄位的值不相等,則回傳 FALSE

matches[form_item]

is_unique

Yes

如果表單元素的值與指定資料表欄位有重複,則回傳 False(譯者注:比如 is_unique[User.Email],那麼驗證類別會去查詢 User 表中 Email 欄位有沒有與表單元素一樣的值,如存重複,則回傳 false,這樣開發者就不必另寫 Callback 驗證程式碼。)

is_unique[table.field]

min_length

Yes

如果表單元素值的字元長度少於參數中定義的數字,則回傳 FALSE

min_length[6]

max_length

Yes

如果表單元素值的字元長度大於參數中定義的數字,則回傳 FALSE

max_length[12]

exact_length

Yes

如果表單元素值的字元長度與參數中定義的數字不符,則回傳 FALSE

exact_length[8]

greater_than

Yes

如果表單元素值是非數字型別,或小於參數定義的值,則回傳 FALSE

greater_than[8]

less_than

Yes

如果表單元素值是非數字型別,或大於參數定義的值,則回傳 FALSE

less_than[8]

alpha

No

如果表單元素值中包含除字母以外的其他字元,則回傳 FALSE

alpha_numeric

No

如果表單元素值中包含除字母和數字以外的其他字元,則回傳 FALSE

alpha_dash

No

如果表單元素值中包含除字母/數字/下劃線/破折號以外的其他字元,則回傳 FALSE

numeric

No

如果表單元素值中包含除數字以外的字元,則回傳 FALSE

integer

No

如果表單元素中包含除整數以外的字元,則回傳 FALSE

decimal

Yes

如果表單元素中輸入(非小數)不完整的值,則回傳 FALSE

is_natural

No

如果表單元素值中包含了非自然數的其他數值 (其他數值不包括零),則回傳 FALSE。自然數形如:0,1,2,3....等等。

is_natural_no_zero

No

如果表單元素值包含了非自然數的其他數值 (其他數值包括零),則回傳 FALSE。非零的自然數:1,2,3.....等等。

valid_email

No

如果表單元素值包含不合法的 email 地址,則回傳 FALSE

valid_emails

No

如果表單元素值中任何一個值包含不合法的 email 地址(地址之間用英文逗號分割),則回傳 FALSE。

valid_ip

No

如果表單元素的值不是一個合法的 IP 地址,則回傳 FALSE。

valid_base64

No

如果表單元素的值包含除了 base64 編碼字元之外的其他字元,則回傳 FALSE。

Last updated