有些时候我们需要将Django从数据库获取的数据以json的格式传输到前端,比如echarts图表用到的就是json格式的数据。关于Django对象序列化成json,笔者踩了一些坑,最终总结了直观简洁地两种方法。
一、使用Django自带的serializers序列化
Django ORM的 Queryset对象默认无法被直接json.dumps()序列化,django.core提供的serializers模块可以将其序列化成str类型。
例如,在views.py里的代码如下:
def tabledata(request):
mon = MonRota.objects.all().filter(s_time__startswith='2018-02-10')
json_data = serializers.serialize('json', mon)
json_data = json.loads(json_data)
return JsonResponse(json_data, safe=False)
接收到的json数据:
[{
"model": "ops.monrota",
"pk": "1000001",
"fields":
{
"s_time": "2018-02-10T09:00:00Z",
"e_time": "2018-02-10T20:29:59Z",
"name": "Mayun",
}
},
{
"model": "ops.monrota",
"pk": "1000002",
"fields":
{
"s_time": "2018-02-10T20:30:00Z",
"e_time": "2018-02-11T09:59:59Z",
"name": "MaHuateng",
}
}]
可以看到比较详细的信息,例如model名、主键数据。
二、使用json模块中的json.dumps()函数序列化
或许方法一中的json格式并不是你想要的,我们大多数情况需要的都是类似于[{},{}]的二维格式,这时候我们可以用json.dumps()函数来处理。
def tabledata(request):
mon = MonRota.objects.all().filter(s_time__startswith='2018-02-10').values()
json_data = list(mon)
json_data = json.dumps(json_data, cls=DateEncoder, ensure_ascii=False)
return HttpResponse(json_data)
这里我们做了两个指定,cls=DateEncoder
和ensure_ascii=False
,有两个方面的考虑。
一个是解决datetime、date格式数据无法json序列化问题,新定义了一个类DateEncoder()
去处理。
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, datetime.date):
return obj.strftime("%Y-%m-%d")
else:
return json.JSONEncoder.default(self, obj)
另外,json.dumps() 序列化时对中文默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=False
。
接收到的json数据:
[{
"id": "1000001",
"s_time": "2018-02-10T09:00:00Z",
"e_time": "2018-02-10T20:29:59Z",
"name": "Mayun",
},
{
"id": "1000002",
"s_time": "2018-02-10T20:30:00Z",
"e_time": "2018-02-11T09:59:59Z",
"name": "MaHuateng",
}]
当然,网络上还有序列化成json的其他方法,大家也可以参考,但是个人推荐以上两种,信我少踩坑。
如果你喜欢本文章,还请点个关注和喜欢,我会为大家不断地带来Python学习笔记。