一、在此之前所用的提交数据里面,要么用form表单提交数据,要么使用AJAX提交数据(传值到后端,提交后值依然保存在input框中)。
form表单提交数据 缺点:
1、不能保留上次提交的数据,如果是刷新页面数据依然不会保留。
解决:使用django自带的 Form 组件,对form表单的验证:
∆∆∆Form组件的作用:
1】用户请求数据校验(本质就是正则表达式验证)
2】保留上次输入的内容,生成HTML标签
∆ form表单的缺点,可以使用django 的 Form 组件:
Form组件的使用:
1、定义一个类Form,这个类继承Form: class LoginForm(Form): 字段名=fields.Charfield(max_length=32)#本质就是正则表达式验证 2、实例化一个对象 obj=LoginForm(request.POST)# request.POST 用户从前端传过来的数据 3、判断用户是否在input框中输入值 用 obj.cleaned_data() #cleaned_data 是正确的信息 4、obj.errors() . 这个是用户没输入或者输入的信息没有与Form组件的正则匹配,errors()会返回错误信息到 前端,错误信息如果要在前端展示则需如: <p><input type="text " name="user">{{ obj.errors.user.0 }}</p>
django Form组件使用--代码示例(案例1):
(Form组件与ajax保存上次提交的信息)
views.py
#定义Form组件, class LoginForm(Form): username=fields.CharField(required=True,max_length=48)#这个字段要与前端的input的 name属性一致,不然这个里的fields.CharField(这里的正则表达匹配不到) password=fields.CharField(required=True) def login(request): ret={'status':True,'msg':None) if request.method=='GET': return render(request,'login.html') else: obj=LoginForm(request.POST) if obj.is_valid():
#is_valid()内部原理:
1、获取当前类中所有的字段,当对LoginForm实例化的时候,会把username\password放到self.fields中(也就是说会找到LoginForm中的所有的字段),而里面的字段,包含的就是一个正则表达式
2、is_valid() 里面会循环self.fields,现在里面有usernamae,password两个字段, 也就是说里面的字段数有两个,里面有几个字段是我们来定的
3、is_valid() 里面的结构如:
flag=true
erros=
cleaned_data=
for k,v in self.fields.items():
k就是:usernane, password
v就是: 正则表达式fields.CharField()
input_value=request.POST.get(k)#这是用户提交过来的数据
v正则表达式与input_value做校验,如果成功--则通过,返回一个正确信息 cleaned_data,否则就返回一个错误信息(errors,)
flag=False# 但凡有一个错误,就返回给用户一个False print(obj.cleaned_data) return redirect('http://www.baidu.com') else: print(obj.errors) ret['status']=False ret['msg']=obj.errors v=json.dumps(ret) print(v) return HttpResponse(v) return render('.........')#将正确的信息和错误的信息返回到前端 login.html <form action='/login/' method='POST' id='f1'> {% csrf_token %} username: <input type='text' name='username'> {{ obj.errors.username.0 }} password:<input type='text' name='password'> {{ obj.errors.username.0 }} <a οnclick='submitForm();'>提交</a> </form> <script src='/static/jquery-3.2.1.js'> </script> <script>
function submitForm(){
$('.c1').remove()//先看下面代码(c1.remove表示每次进来先删除多次错误信息,如果不加这个标签会有多次的错误信息,先尝试不加) $.ajax({ url:'/login/', type:'POST', dataType:'JSON', data:$('$f1').serialize(),//它的内部会把form 表单的所有数据拿到,包括csrf_token,,两个input 一个username 一个password ,格式仍然是键值对的形式提交到后台 username='abc'&password='123456'&csrf_token='fdasf#@#3421',它是用&号连接所有的键值
关于serialize()的更多解释:http://www.w3school.com.cn/jquery/ajax_serialize.asp success:function(arg){ consolo.log(arg) if(arg.status){ }else{ $.each(arg.msg,function(index,value){ console.log(index,value); var tag=document.createElenment('span');//创建一个 span标签,用于存放后端传过来的错误信息 tag.innerHTML=value[0];// username – ["This field is required."],拿到的就是username的第一个错误信息 tag.className='c1';//这里再给 span一个样式,目的是当点击提交的时候,没有匹配上的错误信息多次显示,然后与这个函数刚进来的时候清除掉这个错误信息。$('.c1').remove() $('#f1').find('input=[name="'+index+'"]').after(tag);//找到input框name=password 或 name=username的框,在其后加上一个span标签
// 找到 password – ["This field is required."] ,或 username ["This field is required."] }) } } }) } </script>
效果截图
总结:
1、在以后的使用中:
1】ajax: 仅用于验证功能 . ∆∆∆∆∆∆
2】Form组件:用在验证功能,和生成HTML标签 . ∆∆∆∆∆∆
2、django Form组件中的关键字
例:
class CommentForm(Form):
name=fields.CharField(这里面的关键字)
∆ initial ='you name '#input框中的默认值 ,fields.DateField(initial=datetime.date.today,), ∆ auto_id =False #是否自增 ∆ label = 'your name ' #label='Username: ' :就是input标签前面的文字, ∆ ∆ widge: 与widgets配合使用,指定生成一个radio 标签 例如:性别选择 : Choice=(('1','male'),('2','famale')) gender=fields.ChoiceField(widge=widgets.RadioSelect,choices=Choice)
∆ CharField() #字符串
∆ IntergerField # 数字
∆ EmailField #限制只能输入邮箱格式: Example: fields.EmailField
∆ URLField() #只能输入URL类型的字段
∆ SlugField() #字母、数字、下划线
∆ GenericIPAddressField() # iP 地址类型输入
∆ DateTimeField #时间类型输入
∆ RegexField('138\d+') ##自定制格式 ,可以设置,最长、最短、是否为空、
˚˚˚˚上述字段的本质就是正则表达式,如果这些规则不够,就用自己写的正则表达式˚˚¬˚˚˚˚˚
优化 简写案例一,前端标签都则django Form组件生成 :views.py 文件 :
from django.forms import Form,fields,widgets,forms import datetime,time import json class LoginForm(Form): username=fields.CharField(required=True,max_length=48, label='Username: ') password=fields.CharField(required=True) Choice=(('1','famale'),('2','male')) gender=fields.ChoiceField(widget=widgets.RadioSelect,choices=Choice) date=fields.DateField(initial=datetime.date.today) def login(request): ret={'status':True,'msg':None} if request.method=='GET': obj=LoginForm()#保存这个input框的值,前端必须写{{ obj.username }} {{ obj.errors.username.0 }} return render(request,'login.html',{'obj':obj})#obj---> 它的内部就是给前端生成 一个input框 ,内部中有个__str__:<input type='text' name='t2'>
如果没有传任何值的话,就是一个空的input框
else: print(obj.errors) ret['status']=False ret['msg']=obj.errors v=json.dumps(ret)# 现在这里有值了,这个有值的input框,就多了个value, print(obj.cleaned_data)#用户提交过来的值 cleaned_data 前端的input 的value就多了个value={{ obj.username }} ,cleaned_data :表示前端输入了正确的值
return HttpResponse(v) return render(request,'login.html',{'obj':obj,'v':v}) ∆标签不手写,全由后端控制: <form action='/login/' method='POST' id='f1'> {% csrf_token %} {{ obj.date }} <p>{{ obj.gender }}</p> <p>{{ obj.username.label }} {{ obj.username }} {{ obj.errors.username.0 }} </p> <p>{{ obj.password }} {{ obj.errors.password.0 }} </p> <p><a οnclick='submitForm();'>提交</a></p> </form> <script src='/static/jquery-3.2.1.js'></script> <script> function submitForm(){ $('.c1').remove() $.ajax({ url:"/login/", type:'POST', dataType:'JSON', data:$('#f1').serialize(), success:function(arg){ if(arg.status){ }else{ $.each(arg.msg,function(index,value){ console.log(index.value) var tag=document.createElement("span"); tag.inneHTML=value[0]; tag.className='c1'; $('#f1').find('input[name=" '+index+' "]').after(tag); }) } } }) } </script>
再来一例:
注册表单:
自定义验证规则:
views.py
class RegisterForm(Form): user=fields.charField(max_length=43) email=fields.EmailField() password=fields.CharField() phone=fields.RegexField('139\d+') def register(request): if request.method=='GET': obj=RegisterForm() return render(request,'register.html',{'obj':obj}) else: obj=RegisterForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) else: print(obj.errors) return render(request,'register.html',{'obj':obj}) register.html <form action='/register/' method='POST' novalidate> {% csrf_token %} <p> {{ obj.user }} {{ obj.errors.user.0 }} </p> <p> {{ obj.password }}{{ obj.errors.password.0 }} </p> <p> {{ obj.phone }}{{ obj.errors.phone.0 }} </p> <input type='submit' values='提交'> </form>
Form表单中自定义错误信息:
#自定义错误信息 class TestForm(Form): t1=fields.CharField(required=True,max_length=8,min_length=2, label='www.baidu.com',#前端obj.label_t1 访问 initial='321',#初始值 help_text='22', #自定义错误信息 error_messages={ 'required':'不能为空', 'max_length':'too long', 'min_length':'to short', }) t2=fields.IntegerField( max_value=10000, min_value=10, error_messages={ 'required':'t2不能为空', 'invalid':'T2格式错误,必须是数字', 'max_value':'大于10000', 'min_value':'小于10', }, ) #Interger 是默认是 required True #邮箱格式继承CharField t3=fields.EmailField( error_messages={ 'required':'不能为空', 'invalid':'t3格式错误,必须是邮箱格式', }, disabled=True,#是否可以 编辑 label_suffix='' )
利用Form 组件做的增、删、改、查(学生表与教师表)
http://pan.baidu.com/s/1sl6V31j # year2017/mon7/day/s4day772下