django进阶之form表单

form 表单

form 表单主要2个功能,用户输入验证和生成HTML标签

用户输入验证

  1. 字段是否为空
  2. 字段格式是否正确
  3. 自定义验证,例如:用户两次输入的密码是否一致

例如:用户注册页面,实现用户名/密码的验证

1
2
3
4
5
6
7
8
9
10
11
12
13
from 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
6
from 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
8
from 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
59
from 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 确定显示的位置

Recommended Posts