功能:1.对用户请求的验证
2.生成HTML代码
普通表单应用:
views.py
from django.shortcuts import render,HttpResponse
from django import forms
from django.forms import fields
# Create your views here.
class MyForm(forms.Form):
user=fields.CharField(max_length=15,min_length=5,required=True,
error_messages={
'max_length':'长度小于15',
'min_length': '长度大于5',
'required': '不能为空'
})
password = fields.CharField(max_length=15, min_length=5, required=True,
error_messages={
'max_length':'长度小于15',
'min_length': '长度大于5',
'required': '不能为空'
})
age = fields.IntegerField(required=True,
error_messages={
'invalid': '必须为数字',
'required': '不能为空'
})
email=fields.EmailField(required=True,
error_messages={
'invalid': '邮箱格式不正确',
'required': '不能为空'
})
def form1(request):
if request.method=='GET':
obj = MyForm()
return render(request,'form1.html',{'obj':obj})
if request.method=='POST':
obj=MyForm(request.POST)
if obj.is_valid():
print('成功',obj.cleaned_data)
else:
print('失败',obj.errors)
return render(request,'form1.html',{'obj':obj})
form1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/form1/" method="post">
<p>用户名{{ obj.user }}{{ obj.errors.user.0 }}</p>
<p>密码{{ obj.password }}{{ obj.errors.password.0 }}</p>
<p>年龄{{ obj.age }}{{ obj.errors.age.0 }}</p>
<p>邮箱{{ obj.email }}{{ obj.errors.email.0 }}</p>
<input type="submit" name="提交">
</form>
</body>
</html>
Ajax应用
views.py
def ajaxform(request):
import json
dic={'status':None,'data':None,'err_msg':None}
if request.method=='GET':
obj=MyForm()
return render(request,'ajaxform.html',locals())
if request.method=='POST':
obj=MyForm(request.POST)
if obj.is_valid():
dic['status']='success'
dic['data']=obj.cleaned_data
print(dic)
dic_str=json.dumps(dic)
return HttpResponse(dic_str)
else:
dic['status']='error'
# print(obj.errors.as_ul()) # 默认ul
# print(obj.errors.as_json())
# print(obj.errors.as_data())
dic['err_msg']=obj.errors
print(dic)
dic_str = json.dumps(dic)
return HttpResponse(dic_str)
ajaxform.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jquery-3.3.1.js"></script>
</head>
<body>
<form id="fom" >
<p>用户名{{ obj.user }}</p>
<p>密码{{ obj.password }}</p>
<p>年龄{{ obj.age }}</p>
<p>邮箱{{ obj.email }}</p>
<input type="button" value="提交" id="btn">
</form>
</body>
</html>
<script>
$('#btn').click(function () {
$.ajax({
url:'/ajaxform/',
type:'POST',
data:$('#fom').serialize(),
dataType:'JSON',
success:function (arg) {
if(arg.status=='success'){
window.location.href='https://www.baidu.com/'
}else{
console.log(arg.err_msg)
}
}
})
})
</script>
1.普通表单与Ajax对比:
1.Ajax的错误信息要自己展示
2.Ajax的跳转要自己跳转
了解:json只能转换python的基本数据类型,
type(obj.errors)
>>><class 'django.forms.utils.ErrorDict'>
而ErrorDict继承了dic
2.创建Form类时,主要涉及到 【字段】 和 【插件】(字段用于对用户请求数据的验证,插件用于自动生成HTML)
views.py
from django.shortcuts import render,HttpResponse
from django import forms
from django.forms import fields
from django.forms import widgets
# Create your views here.
class MyForm(forms.Form):
user=fields.CharField(
max_length=15,
min_length=1,
required=True,
label='用户名',
initial='请输入用户名',
help_text='asdfasd',
show_hidden_initial=True,
validators = [],#自定制验证规则
disabled=True,
label_suffix=':',
widget=widgets.TextInput(attrs={'id':123}),
error_messages={
'max_length':'长度大于15',
'min_length': '长度小于1',
'required': '不能为空'
}
)
password = fields.CharField(max_length=15, min_length=1, required=True,
error_messages={
'max_length':'长度大于15',
'min_length': '长度小于1',
'required': '不能为空'
},
label='密码'
)
age = fields.IntegerField(required=True,
error_messages={
'invalid': '必须为数字',
'required': '不能为空'
},
label='年龄'
)
email=fields.EmailField(required=True,
error_messages={
'invalid': '邮箱格式不正确',
'required': '不能为空'
},
label='邮箱'
)
classes = fields.CharField(
max_length=15,
min_length=1,
required=False,
error_messages={
'max_length': '长度大于15',
'min_length': '长度小于1',
'required': '不能为空'
},
widget=fields.Select(),
label='班级'
)
file=fields.FileField()
img=fields.ImageField(required=False)
city=fields.ChoiceField(
choices=[(1,'北京'),(2,'上海'),(3,'大连'),],
initial=3,
)#单选
cityA=fields.CharField(
widget=widgets.Select(choices=[(1,'北京'),(2,'上海'),(3,'大连'),])
)#单选
cityB = fields.IntegerField(
widget=widgets.Select(choices=[(1, '北京'), (2, '上海'), (3, '大连'), ])
)#单选
city1 = fields.MultipleChoiceField(
choices=[(1, '北京'), (2, '上海') ],
initial=2,
widget=widgets.RadioSelect
) # 多选
city2=fields.MultipleChoiceField(
choices=[(1,'北京'),(2,'上海'),(3,'大连'),],
initial=[2,3],
widget=widgets.SelectMultiple(attrs={'id':666})
)#多选
city3 = fields.MultipleChoiceField(
choices=[(1, '北京'), (2, '上海'), (3, '大连'), ],
initial=[2, 3],
widget=widgets.CheckboxSelectMultiple
) # 多选
def form1(request):
if request.method=='GET':
obj = MyForm()
return render(request,'form1.html',{'obj':obj})
if request.method=='POST':
obj=MyForm(request.POST,request.FILES)
if obj.is_valid():
print('成功',obj.cleaned_data)
else:
print('失败',obj.errors)
return render(request,'form1.html',{'obj':obj})
form1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/form1/" method="post" novalidate enctype="multipart/form-data">
<p>{{ obj.user.label }}{{ obj.user }}{{ obj.errors.user.0 }}</p>
<p>{{ obj.password.label }}{{ obj.password }}{{ obj.errors.password.0 }}</p>
<p>{{ obj.age.label }}{{ obj.age }}{{ obj.errors.age.0 }}</p>
<p>{{ obj.email.label }}{{ obj.email }}{{ obj.errors.email.0 }}</p>
<p>{{ obj.classes.label }}{{ obj.classes }}{{ obj.errors.classes.0 }}</p>
<p>{{ obj.file.label }}{{ obj.file }}</p>
<p>{{ obj.img.label }}{{ obj.img }}</p>
<p>{{ obj.city.label }}{{ obj.city }}</p>
<p>{{ obj.city1.label }}{{ obj.city1 }}</p>
<p>{{ obj.cityA.label }}{{ obj.cityA }}</p>
<p>{{ obj.cityB.label }}{{ obj.cityB }}</p>
<p>{{ obj.city2.label }}{{ obj.city2 }}</p>
<p>{{ obj.city3.label }}{{ obj.city3 }}</p>
<input type="submit" name="提交">
{# {{ obj.as_p }}#}
</form>
</body>
</html>
3.Form组件之动态绑定数据(一)
views.py
class MyForm2(forms.Form):
price=fields.IntegerField(
label='价格'
)
user_id=fields.CharField(
label='姓名',
# widget=widgets.Select(choices=models.people.objects.values_list('id','username'))
widget=widgets.Select()
)
def __init__(self,*args,**kwargs):
super(MyForm2,self).__init__(*args,**kwargs)
self.fields['user_id'].widget.choices=models.people.objects.values_list('id','username')
def form2(request):
if request.method=='GET':
obj = MyForm2()
return render(request,'form2.html',{'obj':obj})
if request.method=='POST':
obj=MyForm2(request.POST,request.FILES)
if obj.is_valid():
print('成功',obj.cleaned_data)
else:
print('失败',obj.errors)
return render(request,'form2.html',{'obj':obj})
form2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/form1/" method="post" novalidate enctype="multipart/form-data">
<p>{{ obj.price.label }}{{ obj.price }}{{ obj.errors.price.0 }}</p>
<p>{{ obj.user_id.label }}{{ obj.user_id }}{{ obj.errors.user_id.0 }}</p>
<input type="submit" name="提交">
{# {{ obj.as_p }}#}
</form>
</body>
</html>

3.自定义正则
from django.core.validators import RegexValidator
class MyForm3(forms.Form):
from django.core.validators import RegexValidator
tel = fields.CharField(
label='电话',
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '请以159开头')]
)
4.1自定义单个字段验证
class MyForm(forms.Form):
user = fields.CharField(
max_length=15,
min_length=1,
required=True,
label='用户名',
initial='请输入用户名',
help_text='asdfasd',
show_hidden_initial=True,
validators=[], # 自定制验证规则
disabled=True,
label_suffix=':',
widget=widgets.TextInput(attrs={'id': 123}),
def clean_user(self):
from app01 import models
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
v = self.cleaned_data['user']
if models.people.objects.filter(username=v).count():
raise ValidationError('用户名已存在')
return v
4.2整体字段验证
views.py
class MyForm4(forms.Form):
user = fields.CharField(
label='电话',
)
age = fields.IntegerField(
label='年龄',
)
def clean(self):
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
value_dict=self.cleaned_data
v1=value_dict['user']
v2 = value_dict['age']
if v1=='root'and v2==22:
raise ValidationError('整体错误')
return self.cleaned_data
def form4(request):
if request.method == 'GET':
obj = MyForm4()
return render(request, 'form4.html', {'obj': obj})
if request.method == 'POST':
obj = MyForm4(request.POST, request.FILES)
if obj.is_valid():
print('成功', obj.cleaned_data)
else:
print('失败', obj.errors)
return render(request, 'form4.html', {'obj': obj})
from4.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/form4/" method="post" novalidate enctype="multipart/form-data">
<p>{{ obj.user.label }}{{ obj.user }}{{ obj.errors.user.0 }}</p>
<p>{{ obj.age.label }}{{ obj.age }}{{ obj.errors.age.0 }}</p>
<input type="submit" name="提交">
{# {{ obj.as_p }}#}
</form>
</body>
</html>
5.Form组件上传文件
5.1普通上传文件
# author: Administrator
# date:2018/5/28 0028
from django.shortcuts import render,HttpResponse
def test1(request):
if request.method=='GET':
return render(request,'test1.html')
if request.method=='POST':
obj=request.FILES.get('file')
print(obj.name)
print(obj.size)
f=open(obj.name,'wb')
for item in obj.chunks():
f.write(item)
f.close()
return HttpResponse('...')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/test1/" enctype="multipart/form-data" method="post">
{% csrf_token %}
<input type="file" name="file">
<input type="submit" value="提交">
</form>
</body>
</html>
5.2 美化上传按钮
关键在于文件上传 的透明度设置为0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/test1/" enctype="multipart/form-data" method="post">
{% csrf_token %}
<div style="position: relative;top: 200px;left: 200px;">
<span style="background-color:lightseagreen">上传</span>
<input type="file" name="file" style="opacity: 0;position: absolute;top: 0;left: 0;">
</div>
<input type="submit" value="提交">
</form>
</body>
</html>