form 表单
用户输入验证
- 字段是否为空
- 字段格式是否正确
- 自定义验证,例如:用户两次输入的密码是否一致
例如:用户注册页面,实现用户名/密码的验证1
2
3
4
5
6
7
8
9
10
11
12
13from django.forms import Form
from django.forms import fields
from django.forms import widgets
class RegisterForm(Form):
username = fields.CharField(
required=True,
min_length=3,
max_length=6,
error_messages={"required": "用户名不能为空"},
widget=widgets.TextInput(attrs={'class': 'c1'})
)
通过自定义类,继承 Form
表单,类属性就是对应 models
字段,建议两者一致
CharField 表示字段类型(还有其他类型,例如整型、日期、浮点型、IP地址等)
required 表示是否必填
error_messages 错误提示信息
生成标签
主要针对 templates
模板,可以自动生成标签;提供 css 接口,通过选择器自定义样式widgets
textinput 表示类型(还有其他类型,例如单选、多选等)attr
中的 class c1 表示该文本框中定义的css name=c1(可以定义其他属性)
实例
用户注册页面,输入用户名和密码,密码需要二次确认,均不允许为空models.py
1
2
3
4
5
6from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32, null=True, verbose_name="用户名")
password = models.CharField(max_length=32, null=True, verbose_name="密码")
urls.py
1
2
3
4
5
6
7
8from django.conf.urls import url
from django.contrib import admin
from demo01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register),
]
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59from django.shortcuts import render, HttpResponse, redirect
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from demo01 import models
from django.core.exceptions import ValidationError
class RegisterForm(Form):
username = fields.CharField(
required=True,
min_length=3,
max_length=6,
error_messages={"required": "用户名不能为空"},
widget=widgets.TextInput(attrs={'class': 'c1'})
)
password = fields.CharField(
min_length=4,
max_length=8,
error_messages={'required': '密码不能为空'},
widget=widgets.PasswordInput(attrs={'class': 'c1'})
)
pwd_confirm = fields.CharField(
min_length=4,
max_length=8,
error_messages={'required': '密码不能为空'},
widget=widgets.PasswordInput(attrs={'class': 'c1'})
)
def clean(self):
try:
pwd = self.cleaned_data['password']
pwd_confirm = self.cleaned_data['pwd_confirm']
if pwd == pwd_confirm:
del self.cleaned_data['pwd_confirm']
return self.cleaned_data
else:
self.add_error('pwd_confirm', ValidationError('密码输入不一致'))
return self.cleaned_data
except KeyError as e:
return self.cleaned_data
def register(request):
if request.method == 'GET':
form = RegisterForm()
return render(request, 'register.html', {'form': form})
else:
form = RegisterForm(request.POST)
if form.is_valid(): # 验证表单是否符合规则
models.UserInfo.objects.create(**form.cleaned_data)
print(form.cleaned_data['pwd'])
print(form.cleaned_data['pwd_confirm'])
return HttpResponse('注册成功')
else:
print(form.errors)
return render(request, 'register.html', {'form': form})
- 说明
form.is_valid()
处会验证用户输入是否符合自定义类中各个属性的规则
调用is_valid()
方法后会执行clean()
方法,自定义的验证方法可以重写 clean() 方法实现
自定义的错误提示信息可以通过add_error()
方法传入cleaned_data
中保存表单所有 post 的数据
templates/register.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" novalidate>
{% csrf_token %}
<p>用户名:{{ form.username }} {{ form.errors.username.0 }}</p>
<p>密码:{{ form.password }} {{ form.errors.password.0 }}</p>
<p>确认密码:{{ form.pwd_confirm }} {{ form.errors.pwd_confirm.0 }}</p>
<input type="submit" value="提交"/>
</form>
</body>
</html>
form.errors
保存所有的错误信息,若无则不显示,若有则根据 key 确定显示的位置