Django的序列化
在开发TMS的过程中,后期经常采用一个页面由几个url的数据共同构成的情况,比如,Root提供显示面板,table1提供面板中某个Table表格的数据来源,chart1提供面板中某个图表的数据来源。而在Root的html模板中,使用ajax发送访问table1和chart1的请求,并获取返回的Json数据。
是的。ajax通常得到的是JsonResponse格式的返回数据,因此,我们需要想办法将Django查询的QuerySet转换成Json格式输出,即,序列化。
一、目前我使用的方法
QuerySet的序列化
先使用values
将所需字段弄成QuerySet
中类似Dict
的存在,然后转换成list
@ajax_required
def testcaseDeps(request):
"""按部门统计某年内的各部分更新、修改的用例数"""
year = request.GET.get('year')
qs = swtTestCase.objects.filter(createDate__year=year).values('team').\
annotate(adds=swtTestCase.ADD, dels=swtTestCase.DEL, mods=swtTestCase.MOD, news=swtTestCase.NEW)
return JsonResponse(dict(datas=list(qs)))
RawQuerySet的序列化
RawQuerySet如果不带其他表格的字段,可通过Django提供的serializers来序列化(其实对于上面QuerySet也一样)。但是如果查询的时候带别的Table的字段,比如,使用left join后的查询结果,那么使用该方法序列化后不带额外需要的字段,需要自己写方法进行处理。
from django.core import serializers
query = 'select * from users_user'
data = serializers.serialize('json', User.objects.raw(query))
query = "SELECT users_user.displayName, users_remindjira.* from users_user left join users_remindjira on users_user.username=users_remindjira.`user` where users_remindjira.day = '{}' and users_user.dep_id='{}'".format(t, depId)
qs = RemindJira.objects.raw(query)
def rawList(qsIn):
"""将查表得到的RawQuerySet转换成[{},{}]格式,方便用于后面的转换成Json格式的输出"""
myout = []
for item in qsIn:
tt = item.__dict__
tt.pop('_state')
tt.pop('id')
myout.append(tt)
return myout
return JsonResponse(dict(datas=rawList(qs)))
二、Django自带的模型转字典方法
Django自带的模型转字典的方法是model_to_dict,使用它的话,一是只针对单个对象,需要对QuerySet中的所有元素逐个进行处理;二是图片、文件之类的字段无法转换。
from django.forms.models import model_to_dict
queryset = Publisher.objects.all()
data = []
for i in queryset:
data.append(model_to_dict(i))
import json
return HttpResponse(json.dumps(data), content_type='application/json')
三、serializers
上面讲处理RawQuerySet的时候已经提过一次了。但是它给出的json字段格式与我们期望的稍有不同
from django.core import serializers
qs = User.objects.all()
rzt = serializers.serialize('json', qs)
return HttpResponse(rzt)
它出来的结果如下:
>>>print(json.loads(rzt)[0])
{'model': 'users.user',
'pk': 53,
'fields': {
'password': 'pbkdf2_sha256$150000$nCgM7okk79UN$kGIjI8hyzBGzyZe1cfpJRMP+Plm6GGpSXRzIxg9xgTM=',
'last_login': None,
'is_superuser': False,
'username': 'biwenqing',
'first_name': '',
'last_name': '',
'email': 'biwenqing@hisense.com',
'is_staff': False,
'is_active': False,
'date_joined': '2020-04-22T13:04:44.617Z',
'dep': '手机专项测试室',
'displayName': '毕文青',
'mobile': None,
'employeeNumber': None,
'telephone': None,
'groups': [5],
'user_permissions': []}
}
可以看到,它额外加了一些东西(pk,model),而我们实际需要的都在fields中。
四、Django的rest_framework
JSON格式
对象 {键:值, }
数组 [值 , 值 ]
对象中的值可以为数组;数组中值可以为对象