功能: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>