概要

通常情况下,我们需要⾃⼰⼿动在HTML⻚⾯中,编写form标签和其内的其它元 素。但这费时费⼒,⽽且有可能写得不太恰当,数据验证也⽐较麻烦。有鉴于此, Django在内部集成了⼀个表单模块,专⻔帮助我们快速处理表单相关的内容。 Django的表单模块给我们提供了下⾯三个主要功能:

  • 准备和重构数据⽤于⻚⾯渲染
  • 为数据创建HTML表单元素
  • 接收和处理⽤户从表单发送过来的数据
  • 验证表单数据的合法性

Form相关的对象包括

基本使用

说明

Form对象封装了⼀系列Field和验证规则,Form类都必须直接或间接继承⾃ django.forms.Form,定义Form有两种⽅式:

  • 导入django的forms
1
from django import forms
  • 直接继承Form
1
2
class XXXForm(forms.Form):
# 验证信息
  • 结合Model,继承django.forms.ModelForm,这种方式虽然简单,但很多内置验证无法使用
1
2
3
4
5
6
7
class XXX(models.Model):
字段 = models.CharField(max_length=30)
字段 = models.CharField(max_length=20)
class XXXForm(ModelForm):
class Meta:
model = XXX
field = ('字段', '字段') # 只显示model中指定的字段,显示所有是⽤'__all__'

示例代码

  • 创建表单模型

在应用目录下新建forms.py文件,导入django的forms库:

1
2
3
4
5
6
from django import forms

class RegisterForm(forms.Form):
username = forms.CharField(required=True, error_messages={
'required': '用户名必须输入'
})
  • 创建模板

表单里的name和forms里的名字必须一致,不一致没法验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form action="/admin/register/" method="post">
用户名:<input type="text" name="username">
<input type="submit" value="注册">
</form>
<!--把验证不通过信息输出到前台-->
{{ forms.errors }}
</body>
</html>
  • 创建视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def register(request):
if request.method=='POST':
# 导入表单模型
from App.forms import RegisterForm
# 实例化表单模型类
forms = RegisterForm(request.POST)
# 进行表单验证 验证通过返回True,否则False
if forms.is_valid():
# 表单验证通过,把数据输出
data = forms.cleaned_data
print(data)
return HttpResponse('表单验证通过')
else:
# 表单验证不通过把表单信息传到前台
return render(request, 'register.html', {'forms': forms})
return render(request, 'register.html')

常用的field类

核心字段

参数名 说明
required 给字段添加必填属性,不能空着,若要表示⼀个字段不是 必需的,设置required=False
error_messages 该参数允许你覆盖字段引发异常时的默认信息。 传递的是 ⼀个字典,其值为你想覆盖的错误信息
validators 指定⼀个列表,其中包含了为字段进行验证的函数

核心字段参数

参数名 说明
CharField 默认的Widget:TextInput
空值:’’(⼀个空字符串)
规范化为:⼀个Unicode 对象。 如果提供,验证max_length 或 min_length。 否则,所有的输⼊都是合法的。
错误信息的键:required, max_length, min_length

Form常用属性和方法

名称 说明 示例
cleaned_data(字典) 表单中验证通过的⼲净数 据 form.cleaned_data
form.cleaned_data.get(‘username’)

重写验证

说明

  • 单个字段验证
    • 方法名就必须为clean_字段名
    • 只能取自己当前字段值
  • 全局字段验证
    • 方法名clean

注意事项

  • 必须有返回值

  • 抛出异常使用:raise ValidationError(‘XXX’)

  • forms.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
from django import forms
from django.core.exceptions import ValidationError

class RegisterForm(forms.Form):
username = forms.CharField(required=True, error_messages={
'required': '用户名必须输入'
})
password = forms.CharField(required=True, error_messages={
'required': '密码必须输入'
})
ispassword = forms.CharField(required=True,error_messages={
'required': '确定密码必须输入'
})

# 单个字段验证
def clean_password(self):
password = self.cleaned_data.get('password')
if password.isdigit():
raise ValidationError('密码不能是纯数字')
return password

# 全局验证
def clean(self):
print(1111)
password = self.cleaned_data.get('password', None) # 使用get方法,如果没有password这个键,返回None
ispassword = self.cleaned_data.get('ispassword', '')
print(password,ispassword)
if password != ispassword:
# 如果是全局验证,ValidationError的参数是一个字典,键为表单name,值为报错内容
raise ValidationError({"ispassword":"两次密码不一致"}) # raise如果发送错误调用ValidationError函数,后面代码不在执行
return self.cleaned_data
  • 自定义前台样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form action="/admin/register/" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
确定密码:<input type="password" name="ispassword"><br>
<input type="submit" value="注册">
{% for form in forms.password.errors %}
<h1>{{ form }}</h1>
{% endfor %}
</form>

</body>
</html>