Django里面,当我们使用post提交form的时候,如果出现了错误,我们可以直接把错误通过obj传回给前端。如果当我们使用Ajax方式和自定义的form提交数据,这个时候就需要在后端把错误信息序列化,然后传回前端进行反序列化了。
对于错误信息,django提供了几种转换的方式。
第一种是as_json,他可以把整个错误信息转换为字符串的格式,这样子我们可以直接序列化json.dumps传到前端去。他的问题在于这个错误信息是一个嵌套的字典,意味着在前端需要反序列化2次才能获取正确的信息。
view.py
from django import formsfrom django.forms import widgets, fields
class LoginForm(forms.Form):
username = fields.CharField()
password = fields.CharField(
max_length=64,
min_length=12
)
def login(request):
import json
res = {'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.cleand_data)
else:
# print(obj.errors, type(obj.errors))
res['error'] = obj.errors.as_json() # 转为json格式
return HttpResponse(json.dumps(res))
login.html
<body>
<form id="fm">
{% csrf_token %}
<p><input type="text" name="username" /></p>
<p><input type="password" name="password" /></p>
<a id="submit">ajax提交</a>
</form>
<script src="/static/jquery-1.12.4.js"></script>
<script>
// 页面框架加载完自动执行
$('#submit').click(function(){
$.ajax({
url:'/login.html',
type:'POST',
data:$('#fm').serialize(),
success:function(arg){
console.log(arg);
arg = JSON.parse(arg); // 转为字典
console.log(arg);
},
error: function(){
}
})
})
</script>
</body>
一种优化的方法是自定义一个Json的报错格式,通过判断isinstance(filed, XXX) 里面 XXX的类型,我们手动执行不同的操作
from django import forms
from django.forms import widgets, fields
class LoginForm(forms.Form):
username = fields.CharField()
password = fields.CharField(
max_length=64,
min_length=12
)
# 序列化,转换为指定数据类型
import json
from django.core.exceptions import ValidationError
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, ValidationError):
return {'code':field.code, 'messages': field.messages}
else:
return json.JSONEncoder.default(self, field)
def login(request):
res = {'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.cleand_data)
else:
# print(obj.errors, type(obj.errors))
# res['error'] = obj.errors.as_json() # 转为json格式
print(type(obj.errors.as_data()))
for k,v in obj.errors.as_data().items():
print(k,v) # 这里v是ValidationError类型,不能序列化
res['error'] = obj.errors.as_data()
result = json.dumps(res, cls=JsonCustomEncoder)
return HttpResponse(json.dumps(result))
类似的,当我们操作时间数据的时候,默认他没法序列化,我们可以通过类似的方法进行转换
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return o.strftime('%Y-%m-%d') # 转成字符串类型
else:
return json.JSONEncoder.default(self, field)
v = {'k':'123', "k1":datetime.datetime.now()}
ds = json.dumps(v, cls=JsonCustomEncoder)
最后看看其他类型的序列化
对QuerySet的序列化
from django.core import serializers
v = models.tb.objects.all()
data = serializers.serialize("json", v)
对QuerySet value结构的序列化
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return field.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field)
v = models.tb.objects.values('id','name','ctime')
v = list(v) # 把(类似列表的queryset类型)转换为列表
v = json.dumps(v,cls=JsonCustomEncoder) # 这里cls只对ctime操作。
# 如果没有ctime这个类型,只写上边的三句就可以实现
以上资料出自老男孩的培训视频~