day22-Form内置序列化错误信息
一、前言
今天我们来用个一个ajax的例子,来说明form的验证,还有一个就是,我们json.dumps的只能是python简单的数据类型,但是如果遇到复杂的数据类型,json.dumps是序列化不了的,那这个怎么办呐。我们用什么办法解决呐,下面我们就来学习一下,这个东西,还有一个就是我们在写,views代码的时候,我们可以另外建一个文件夹,所以我们整体的目录结构如下:
-sday22 -app01 #app名字 migrations #初始化数据库的 views #写业务代码的 - __init__.py - accounts.py #用户验证 - blogs.py #博客业务代码 - ... ..... forms #写forms验证的 - __init__.py - froms.py #专业做forms验证的 - .... .... - sday22 #项目名 ..... - static #静态资源 .... - templates #模板 ... - manage.py
二、用ajax获取内置序列化错误信息
前提,我们以后的项目编写,都按照上面的目录结构,所以我们的业务代码都是写在view文件夹下的
2.1、路由设置
说明:设置登录的url
from django.urls import path from app01.views import accounts urlpatterns = [ path('login/', accounts.login), ]
2.2、视图函数编写
说明:这边要写很多,这边有from验证,django的序列化的转换,以及登录函数login,为了方便我们写在一个文件里面,但是下面是我分3块去写
1、forms验证
from django import forms from django.forms import fields,widgets class LoginForm(forms.Form): username = fields.CharField() #这跟login.html中的input标签的name属性的值一致 password = fields.CharField( max_length=64, min_length=12 )
2、定义JsonCustomEncoder类
说明:这个类特意是为了处理无法序列化复杂的数据类型的,上面 result = json.dumps(ret,cls=JsonCustomEncoder) #这边cls 是序列化的时候,对每一个字段序列化的时候,都会调用一个它的default方法,会在下面的login函数中用到
from django.core.exceptions import ValidationError import json class JsonCustomEncoder(json.JSONEncoder): #直接在cls=JsonCustomEncoder类名,去序列化复杂的数据类型 def default(self,field): if isinstance(field,ValidationError): #field是否是ValidationError的一个对象 return {'code':field.code,'messages':field.messages} else: return json.JSONEncoder.default(self,field)
3、login函数
说明:序列化的时候,复杂的数据类型,json是处理不了的,所以需要特殊处理,这边要定义个JsonCustomEncoder类
from django.shortcuts import render,HttpResponse import json def login(request): ret = {'status':True,'error':None,'data':None} if request.method == "GET": return render(request,'login.html') elif request.method == "POST": obj = LoginForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) else: # print(type(obj.errors)) # ret['error'] = obj.errors.as_json() # as_data 帮我返回的是原生的字典 # print(type(obj.errors.as_data())) # for k,v in obj.errors.as_data().items(): # print(k,v) # ret = {'k1':'v1','k2':ValueError()} #像这种复杂数据类型,json是不能序列化的,我们只能做局部处理 #from django.forms.utils import ErrorDict #通过源码得知:as_data 帮我返回的是原生的字典,as_json()是类似json格式的字符串 # print(obj.errors.as_json()) #我拿到一个字符串,把这个字符串添加到error中 # from django.core.exceptions import ValidationError #看一下这个异常 ret['error'] = obj.errors.as_data() result = json.dumps(ret,cls=JsonCustomEncoder) #这边cls 是序列化的时候,对每一个字段序列化的时候,都会调用一个它的default方法 return HttpResponse(json.dumps(result))
2.3、模板编写
说明:模板我们用ajax去请求,然后收到数据处理
<body> <form id="fm"> {% csrf_token %} <p><input type="text" name="username" /></p> #这边username 需要跟 from 里面的字段 是一模一样 <p><input type="text" name="password" /></p> <a id="submit">提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script> $(function(){ $('#submit').click(function(){ $.ajax({ url:'/login/', type:'post', data:$('#fm').serialize(), sucess:function(arg){ //console.log(arg); arg = JSON.parse(arg); console.log(arg) }, error:function(){ } }) }) }) </script> </body>
最后返回的数据类型为:
"{\"data\": null, \"status\": true, \"error\": {\"username\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}], \"password\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}]}}"
三、总结
- python中的json函数,只能处理 简单的 数据类型,如果要处理复杂的数据类型,比如:datetime、ValidationError等这种复杂的数据类型,需要协助定义:
JsonCustomEncoder
类,然后json.dumps(ret,cls=JsonCustomEncoder)去引用 - python还有其他的复杂的序列化操作:http://www.cnblogs.com/zhangqigao/articles/8990400.html