form+ajax实现验证
form+ajax实现验证
#obj.errors返回的是ErrorDict,不是字典(虽然继承字典)
#obj.errors.as_json() 返回的字符串(前端要连续反解两次)
#obj.errors.as_data() 返回原生的字典 但是返回value 是ValidationError,不能直接序列化
1)通过errors.as_data()实现数据绑定和返回,errors.as_data() 返回原生的字典 但是返回value 是ValidationError,不能直接序列化, 通过json属性cls转换是ValidationError为字典返回。优点:前端jquery不需要JSON.parse转换两次。
2)通过errors.as_json()实现数据绑定和返回。as_json返回的是字符串。
前端返回:需要两次JSON.parse转换(第一次:HttpResponse返回的是字符串;第二次: 返回的error字典中的value是字符串,需要在转成字典,才可以访问)
示例1:注册信息
#两种方式1:as_data(注意view中绑定方式和模板中jqeury调用方式)
forms.py
1 class RegisterForm(forms.Form): 2 username = fields.CharField( 3 error_messages={"required": "用户名不能为空"}, 4 widget=widgets.Input(attrs={"class": "form-control"}) 5 ) 6 email = fields.EmailField( 7 error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'}, 8 widget=widgets.Input(attrs={"class": "form-control"}) 9 ) 10 password = fields.CharField( 11 error_messages={"required": "密码不能为空"}, 12 widget=widgets.Input(attrs={"class": "form-control"}) 13 ) 14 password2 = fields.CharField(error_messages={"required": "密码不能为空"}, 15 widget=widgets.Input(attrs={"class": "form-control"})) 16 check_code = fields.CharField(error_messages={"required": "验证码不能为空"}, 17 widget=widgets.Input(attrs={"class": "form-control"})) 18 19 def clean_username(self): 20 """ 21 验证用户存不存在 22 :return: 23 """ 24 obj = models.UserInfo.objects.filter(username=self.cleaned_data['username']) 25 # 用户存在返回原来的值 26 if not obj: 27 return self.cleaned_data['username'] 28 else: 29 raise ValidationError(message="用户已存在,请更换其他用户名", code="xxxx")
#views.py
1 from django.core.exceptions import ValidationError 2 class JsonCunstomEncode(json.JSONEncoder): 3 def default(self, field): 4 if isinstance(field,ValidationError): 5 return {"code":field.code,"message":field.message} 6 else: 7 return json.JSONEncoder.default(self,field) 8 9 def register(request): 10 """ 11 注册 12 :param request: 13 :return: 14 """ 15 ret={"status":False,"error":None,"data":None} 16 if request.method=="GET": 17 register_obj=forms.RegisterForm() 18 return render(request, 'register.html',{"register_obj":register_obj}) 19 elif request.method=="POST": 20 register_obj=forms.RegisterForm(request.POST) 21 if register_obj.is_valid(): 22 ret["status"]=True 23 ret["data"]=register_obj.cleaned_data 24 else: 25 ret["error"]=register_obj.errors.as_data() 26 result=json.dumps(ret,cls=JsonCunstomEncode) 27 #不能使用render,使用render返回数据,前端var data1=JSON.parse(arg)转换报错。可以使用HttpResponse直接返回数据 28 #return render(request, 'register.html',{"result":result}) 29 return HttpResponse(result)
模块实现:
1 <div class="register"> 2 <div style="font-size: 25px; font-weight: bold;text-align: center;"> 3 用户注册 4 </div> 5 <form role="form" id="register_form"> 6 {% csrf_token %} 7 <div class="form-group"> 8 <label for="username">用户名</label> 9 <input type="text" class="form-control" id="username" placeholder="请输入用户名" name="username"> 10 <p id="error_username"></p> 11 </div> 12 <div class="form-group"> 13 <label for="email">邮箱</label> 14 <input type="email" class="form-control" id="email" placeholder="请输入邮箱" name="email"> 15 <p id="error_email"></p> 16 </div> 17 <div class="form-group"> 18 <label for="password">密码</label> 19 <input type="password" class="form-control" id="password" placeholder="请输入密码" name="password"> 20 <p id="error_password"></p> 21 </div> 22 <div class="form-group"> 23 <label for="confirm_password">确认密码</label> 24 <input type="password" class="form-control" id="password" placeholder="请输入密码" name="password2"> 25 <p id="error_password2"></p> 26 </div> 27 28 <div class="form-group"> 29 <label for="password">验证码</label> 30 31 <div class="row"> 32 <div class="col-xs-7"> 33 <input type="password" class="form-control" id="password" placeholder="请输入验证码" name="check_code"> 34 <p id="error_check_code"></p> 35 </div> 36 <div class="col-xs-5"> 37 <img src="/check_code.html"> 38 </div> 39 </div> 40 <p id="show_error"></p> 41 </div> 42 <a id="register_a" type="submit" class="btn btn-default" >下一步</a> 43 </form> 44 <script src="/static/js/jquery-1.12.4.js"></script> 45 <script src="/static/js/jquery.cookie.js"></script> 46 <script> 47 $("#register_a").click( 48 function(){ 49 $.ajax({ 50 url:'{% url "register" %}', 51 type:"POST", 52 //headers: {"X-CSRFtoken":$.cookie("csrftoken")},如果是用serialize,他就csrftoken一起发送过去,所以不需要加headers 53 data:$("#register_form").serialize(), 54 success:function(arg){ 55 var data1=JSON.parse(arg); 56 console.log(data1); 57 //#如果返回的状态为false,输出出错的内容 58 if (!data1.status){ 59 //清空所有error p标签的内容 60 $("#register_form").find('p[id*=error_]').each( 61 function(){ 62 $(this).text("") 63 } 64 ) 65 //根据错误信息动态绑定到p标签 66 for (var item in data1.error){ 67 var tmp='#error_'+item+'' 68 $(tmp).text(data1.error[item][0].message); 69 } 70 /* 71 手动绑定标签,但是会存在error中没有的信息报错 72 $("#error_username").text(data1.error["username"][0].message); 73 $("#error_email").text(data1.error.email[0].message); 74 $("#error_password").text(data1.error.password[0].message); 75 $("#error_password2").text(data1.error.password2[0].message); 76 $("#error_check_code").text(data1.error.check_code[0].message); 77 */ 78 } 79 else{ 80 //跳转到后台 81 location.href='{% url "base_info" %}' 82 } 83 } 84 85 }) 86 } 87 ) 88 </script>