|
1 | 1 | # 14.3 表单及验证支持 |
| 2 | +Web开发中我们经常的开发流程如下所示: |
| 3 | + |
| 4 | +- 打开一个网页显示出表单。 |
| 5 | +- 用户填写并提交了表单。 |
| 6 | +- 如果你提交了一些无效的信息,或者可能漏掉了一个必填项,表单将会连同你的数据和错误问题的描述信息重新显示。 |
| 7 | +- 这个过程将继续,直到你提交了一个有效的表单。 |
| 8 | + |
| 9 | +在接收端,脚本必须: |
| 10 | + |
| 11 | +- 检查用户递交的表单数据。 |
| 12 | +- 验证数据是否为正确的类型,合适的标准。例如,如果一个用户名被提交,它必须被验证是否只包含了允许的字符。它必须有一个最小长度,不能超过最大长度。用户名不能是已存在的他人用户名,或者甚至是一个保留字等。 |
| 13 | +- 过滤清理数据使逻辑处理中接收到的数据是安全的。 |
| 14 | +- 如果需要,预格式化数据(数据需要清除空白或者经过HTML编码等等。) |
| 15 | +- 准备数据,插入数据库。 |
| 16 | + |
| 17 | +尽管上面的过程并不是很复杂,但是通常需要编写很多代码,而且为了显示错误信息,在网页中经常要使用多种不同的控制结构。创建表单验证虽简单,实施起来却也枯燥无味。 |
| 18 | + |
| 19 | +## 表单和验证 |
| 20 | +上面我们看到一般开发过程都是相当的复杂,而且都是在重复一样的工作,而且如果需要增加一个表单数据,那么整个流程都需要修改,我们知道在Go里面struct是我们常用的一个数据结构,所以beego的form采用了struct来处理表单信息。 |
| 21 | + |
| 22 | +首先定义一个开发Web应用时相对应的struct,一个字段对应一个form元素,通过struct的tag来定义相应的元素信息和验证信息,如下所示: |
| 23 | + |
| 24 | +type User struct{ |
| 25 | +Username string `form:text,valid:required` |
| 26 | +Nickname string `form:text,valid:required` |
| 27 | +Age int `form:text,valid:required|numeric` |
| 28 | +Email string `form:text,valid:required|valid_email` |
| 29 | +Introduce string `form:textarea` |
| 30 | +} |
| 31 | + |
| 32 | +定义好struct之后我们就可以在controller中这样操作 |
| 33 | + |
| 34 | +func (this *AddController) Get() { |
| 35 | +this.Data["form"] = beego.Form(&User{}) |
| 36 | +this.Layout = "admin/layout.html" |
| 37 | +this.TplNames = "admin/add.tpl" |
| 38 | +} |
| 39 | + |
| 40 | +在模板中这样显示表单 |
| 41 | + |
| 42 | +<h1>New Blog Post</h1> |
| 43 | +<form action="" method="post"> |
| 44 | +{{.form.render()}} |
| 45 | +</form> |
| 46 | + |
| 47 | +上面我们定义好了整个的第一步,从struct到显示表单的过程,接下来就是用户填写信息,服务器端接收数据然后验证,最后插入数据库。 |
| 48 | + |
| 49 | +func (this *AddController) Post() { |
| 50 | +var user User |
| 51 | +form := this.GetInput(&user) |
| 52 | +if !form.Validates() { |
| 53 | +return |
| 54 | +} |
| 55 | +models.UserInsert(&user) |
| 56 | +this.Ctx.Redirect(302, "/admin/index") |
| 57 | +} |
| 58 | + |
| 59 | +## 表单类型 |
| 60 | +以下列表列出来了对应的form元素信息: |
| 61 | +<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder"> |
| 62 | +<tbody><tr> |
| 63 | +<th>名称</th> |
| 64 | +<th>参数</th> |
| 65 | +<th>功能描述</th> |
| 66 | +</tr> |
| 67 | + |
| 68 | +<tr> |
| 69 | +<td class="td"><strong>text</strong></td> |
| 70 | +<td class="td">No</td> |
| 71 | +<td class="td">textbox输入框</td> |
| 72 | +</tr> |
| 73 | + |
| 74 | +<tr> |
| 75 | +<td class="td"><strong>button</strong></td> |
| 76 | +<td class="td">No</td> |
| 77 | +<td class="td">按钮</td> |
| 78 | +</tr> |
| 79 | + |
| 80 | +<tr> |
| 81 | +<td class="td"><strong>checkbox</strong></td> |
| 82 | +<td class="td">No</td> |
| 83 | +<td class="td">多选择框</td> |
| 84 | +</tr> |
| 85 | + |
| 86 | +<tr> |
| 87 | +<td class="td"><strong>dropdown</strong></td> |
| 88 | +<td class="td">No</td> |
| 89 | +<td class="td">下拉选择框</td> |
| 90 | +</tr> |
| 91 | + |
| 92 | +<tr> |
| 93 | +<td class="td"><strong>file</strong></td> |
| 94 | +<td class="td">No</td> |
| 95 | +<td class="td">文件上传</td> |
| 96 | +</tr> |
| 97 | + |
| 98 | +<tr> |
| 99 | +<td class="td"><strong>hidden</strong></td> |
| 100 | +<td class="td">No</td> |
| 101 | +<td class="td">隐藏元素</td> |
| 102 | +</tr> |
| 103 | + |
| 104 | +<tr> |
| 105 | +<td class="td"><strong>password</strong></td> |
| 106 | +<td class="td">No</td> |
| 107 | +<td class="td">密码输入框</td> |
| 108 | +</tr> |
| 109 | + |
| 110 | +<tr> |
| 111 | +<td class="td"><strong>radio</strong></td> |
| 112 | +<td class="td">No</td> |
| 113 | +<td class="td">单选框</td> |
| 114 | +</tr> |
| 115 | + |
| 116 | +<tr> |
| 117 | +<td class="td"><strong>textarea</strong></td> |
| 118 | +<td class="td">No</td> |
| 119 | +<td class="td">文本输入框</td> |
| 120 | +</tr> |
| 121 | + |
| 122 | +</tbody></table> |
| 123 | + |
| 124 | +
|
| 125 | +## 表单验证 |
| 126 | +以下列表将列出可被使用的原生规则 |
| 127 | +<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder"> |
| 128 | +<tbody><tr> |
| 129 | +<th>规则</th> |
| 130 | +<th>参数</th> |
| 131 | +<th>描述</th> |
| 132 | +<th>举例</th> |
| 133 | +</tr> |
| 134 | + |
| 135 | +<tr> |
| 136 | +<td class="td"><strong>required</strong></td> |
| 137 | +<td class="td">No</td> |
| 138 | +<td class="td">如果元素为空,则返回FALSE</td> |
| 139 | +<td class="td"> </td> |
| 140 | +</tr> |
| 141 | + |
| 142 | +<tr> |
| 143 | +<td class="td"><strong>matches</strong></td> |
| 144 | +<td class="td">Yes</td> |
| 145 | +<td class="td">如果表单元素的值与参数中对应的表单字段的值不相等,则返回FALSE</td> |
| 146 | +<td class="td">matches[form_item]</td> |
| 147 | +</tr> |
| 148 | + |
| 149 | + <tr> |
| 150 | + <td class="td"><strong>is_unique</strong></td> |
| 151 | + <td class="td">Yes</td> |
| 152 | + <td class="td">如果表单元素的值与指定数据表栏位有重复,则返回False(译者注:比如is_unique[User.Email],那么验证类会去查找User表中Email栏位有没有与表单元素一样的值,如存重复,则返回false,这样开发者就不必另写Callback验证代码。)</td> |
| 153 | + <td class="td">is_unique[table.field]</td> |
| 154 | + </tr> |
| 155 | + |
| 156 | +<tr> |
| 157 | +<td class="td"><strong>min_length</strong></td> |
| 158 | +<td class="td">Yes</td> |
| 159 | +<td class="td">如果表单元素值的字符长度少于参数中定义的数字,则返回FALSE</td> |
| 160 | +<td class="td">min_length[6]</td> |
| 161 | +</tr> |
| 162 | + |
| 163 | +<tr> |
| 164 | +<td class="td"><strong>max_length</strong></td> |
| 165 | +<td class="td">Yes</td> |
| 166 | +<td class="td">如果表单元素值的字符长度大于参数中定义的数字,则返回FALSE</td> |
| 167 | +<td class="td">max_length[12]</td> |
| 168 | +</tr> |
| 169 | + |
| 170 | +<tr> |
| 171 | +<td class="td"><strong>exact_length</strong></td> |
| 172 | +<td class="td">Yes</td> |
| 173 | +<td class="td">如果表单元素值的字符长度与参数中定义的数字不符,则返回FALSE</td> |
| 174 | +<td class="td">exact_length[8]</td> |
| 175 | +</tr> |
| 176 | + |
| 177 | + <tr> |
| 178 | + <td class="td"><strong>greater_than</strong></td> |
| 179 | + <td class="td">Yes</td> |
| 180 | + <td class="td">如果表单元素值是非数字类型,或小于参数定义的值,则返回FALSE</td> |
| 181 | + <td class="td">greater_than[8]</td> |
| 182 | + </tr> |
| 183 | + |
| 184 | + <tr> |
| 185 | + <td class="td"><strong>less_than</strong></td> |
| 186 | + <td class="td">Yes</td> |
| 187 | + <td class="td">如果表单元素值是非数字类型,或大于参数定义的值,则返回FALSE</td> |
| 188 | + <td class="td">less_than[8]</td> |
| 189 | + </tr> |
| 190 | + |
| 191 | +<tr> |
| 192 | +<td class="td"><strong>alpha</strong></td> |
| 193 | +<td class="td">No</td> |
| 194 | +<td class="td">如果表单元素值中包含除字母以外的其他字符,则返回FALSE</td> |
| 195 | +<td class="td"> </td> |
| 196 | +</tr> |
| 197 | + |
| 198 | +<tr> |
| 199 | +<td class="td"><strong>alpha_numeric</strong></td> |
| 200 | +<td class="td">No</td> |
| 201 | +<td class="td">如果表单元素值中包含除字母和数字以外的其他字符,则返回FALSE</td> |
| 202 | +<td class="td"> </td> |
| 203 | +</tr> |
| 204 | + |
| 205 | +<tr> |
| 206 | +<td class="td"><strong>alpha_dash</strong></td> |
| 207 | +<td class="td">No</td> |
| 208 | +<td class="td">如果表单元素值中包含除字母/数字/下划线/破折号以外的其他字符,则返回FALSE</td> |
| 209 | +<td class="td"> </td> |
| 210 | +</tr> |
| 211 | + |
| 212 | +<tr> |
| 213 | +<td class="td"><strong>numeric</strong></td> |
| 214 | +<td class="td">No</td> |
| 215 | +<td class="td">如果表单元素值中包含除数字以外的字符,则返回 FALSE</td> |
| 216 | +<td class="td"> </td> |
| 217 | +</tr> |
| 218 | + |
| 219 | +<tr> |
| 220 | +<td class="td"><strong>integer</strong></td> |
| 221 | +<td class="td">No</td> |
| 222 | +<td class="td">如果表单元素中包含除整数以外的字符,则返回FALSE</td> |
| 223 | +<td class="td"> </td> |
| 224 | +</tr> |
| 225 | + |
| 226 | + <tr> |
| 227 | + <td class="td"><strong>decimal</strong></td> |
| 228 | + <td class="td">Yes</td> |
| 229 | + <td class="td">如果表单元素中输入(非小数)不完整的值,则返回FALSE</td> |
| 230 | + <td class="td"> </td> |
| 231 | + </tr> |
| 232 | + |
| 233 | +<tr> |
| 234 | +<td class="td"><strong>is_natural</strong></td> |
| 235 | +<td class="td">No</td> |
| 236 | +<td class="td">如果表单元素值中包含了非自然数的其他数值 (其他数值不包括零),则返回FALSE。自然数形如:0,1,2,3....等等。</td> |
| 237 | +<td class="td"> </td> |
| 238 | +</tr> |
| 239 | + |
| 240 | +<tr> |
| 241 | +<td class="td"><strong>is_natural_no_zero</strong></td> |
| 242 | +<td class="td">No</td> |
| 243 | +<td class="td">如果表单元素值包含了非自然数的其他数值 (其他数值包括零),则返回FALSE。非零的自然数:1,2,3.....等等。</td> |
| 244 | +<td class="td"> </td> |
| 245 | +</tr> |
| 246 | + |
| 247 | +<tr> |
| 248 | +<td class="td"><strong>valid_email</strong></td> |
| 249 | +<td class="td">No</td> |
| 250 | +<td class="td">如果表单元素值包含不合法的email地址,则返回FALSE</td> |
| 251 | +<td class="td"> </td> |
| 252 | +</tr> |
| 253 | + |
| 254 | +<tr> |
| 255 | +<td class="td"><strong>valid_emails</strong></td> |
| 256 | +<td class="td">No</td> |
| 257 | +<td class="td">如果表单元素值中任何一个值包含不合法的email地址(地址之间用英文逗号分割),则返回FALSE。</td> |
| 258 | +<td class="td"> </td> |
| 259 | +</tr> |
| 260 | + |
| 261 | +<tr> |
| 262 | +<td class="td"><strong>valid_ip</strong></td> |
| 263 | +<td class="td">No</td> |
| 264 | +<td class="td">如果表单元素的值不是一个合法的IP地址,则返回FALSE。</td> |
| 265 | +<td class="td"> </td> |
| 266 | +</tr> |
| 267 | + |
| 268 | +<tr> |
| 269 | +<td class="td"><strong>valid_base64</strong></td> |
| 270 | +<td class="td">No</td> |
| 271 | +<td class="td">如果表单元素的值包含除了base64 编码字符之外的其他字符,则返回FALSE。</td> |
| 272 | +<td class="td"> </td> |
| 273 | +</tr> |
| 274 | + |
| 275 | +</tbody></table> |
| 276 | + |
2 | 277 |
|
3 | 278 | ## links |
4 | 279 | * [目录](<preface.md>) |
|
0 commit comments