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这个类型,只写上边的三句就可以实现
以上资料出自老男孩的培训视频~
本文出自 “麻婆豆腐” 博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1970282
原文地址:http://beanxyz.blog.51cto.com/5570417/1970282