一、前言
django的ORM框架提供的查询数据库表数据的方法很多,不同的方法返回的结果也不太一样,不同方法都有各自对应的使用场景。
主要常用的查询方法个数是13个,方法返回值是可迭代对象QuerySet的方法只有这8个:all(),filter(),exclude(),order_by(),reverse(),values(),values_list(),distinct();
如果前端人员要求接口返回值的数据类型是json,后端人员要对接口返回值为可迭代对象QuerySet的值通过其他方法间接转成非可迭代对象和非json的数据类型的值并把该值当成JsonResponse类初始化时的其中一个入参data的值,最终把JsonResponse类初始化后的对象当做最终的接口返回值提供给前端人员。
把接口返回值为可迭代对象QuerySet的值通过其他方法间接转成json的数据类型的值的所谓方案,目前只有这3种方案(我们只需要记住这3种即可):
⑴.方案1:使用方法serializers
主要作用:把接口返回值为可迭代对象QuerySet的值转为json的数据类型(即转为python语言里的数据类型为字符串的数据类型)的值;
(这种方案只需要做了解即可,基本用不到)
⑵.方案2:使用方法model_to_dict
主要作用:把接口返回值为可迭代对象QuerySet的值转为python语言里的数据类型为dict的数据类型的值;
(这种方案只需要做了解即可,基本用不到)
⑶.方案3:使用方法value跟方法list结合
主要作用:把接口返回值为可迭代对象QuerySet的值转为python语言里的数据类型为list的数据类型的值;
(这种方案最简单,基本都会用这个,要重点知道怎么用)
细节:
①.问题:为什么视图函数返回值返回给前端页面的数据的数据类型有时需要为json?
大概答案:
目前大多数公司研发团队都是采取前后端分离进行项目开发,可以大大提高项目开发效率和提高维护效率。
所以前端开发人员一般会要求后端开发人员把接口返回值转成数据类型为json的数据传给前端开发人员,前端开发人员拿到该数据类型为json的数据后再单独进行处理并获取到自己想要的字段数据去进行对应html页面的数据加载渲染。
②.问题:json这个数据类型要怎么理解?
大概答案:
json这个数据类型,其实数据类型就是字符串。
json这个数据类型可以理解为是美元,全世界的每个国家都可以通过美元进行交易。
而python提供的任何数据类型都可以理解为人民币,java提供的任何数据类型都可以理解为欧元,php提供的任何数据类型都可以理解为日元,c语言提供的任何数据类型都可以理解为港币,html需要的数据类型必须只能为json。
所以,无论是哪种后端语言编写的接口返回值,如果前端人员要求接口返回值的数据类型是json,后端人员要对接口返回值做数据类型的转化即把原先的数据类型(比如python语言的list数据类型/dict数据类型)转成json的数据类型后才能当成最终的接口返回值。
二、JsonResponse类的源码简单分析
细节:
①.json是目前常用的一种数据格式,有时候我们后端开发人员需要给前端开发人员返回一个json格式的数据,而JsonResponse类就能满足这样的需求。
②.通过【from django.http import JsonResponse】和【class JsonResponse(HttpResponse)】,我们可以知道JsonResponse类它是HttpResponse的的一个子类,从父类继承大部分行为,用来帮助创建json的响应。
1、JsonResponse类的源码如下所示
class JsonResponse(HttpResponse):
"""
An HTTP response class that consumes data to be serialized to JSON.
:param data: Data to be dumped into json. By default only ``dict`` objects
are allowed to be passed due to a security flaw before EcmaScript 5. See
the ``safe`` parameter for more information.
:param encoder: Should be a json encoder class. Defaults to
``django.core.serializers.json.DjangoJSONEncoder``.
:param safe: Controls if only ``dict`` objects may be serialized. Defaults
to ``True``.
:param json_dumps_params: A dictionary of kwargs passed to json.dumps().
"""
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super().__init__(content=data, **kwargs)
2、JsonResponse类的构造函数里的每个入参的大概含义和作用
①.入参【data】:应该传递一个数据类型为dict的值给它(也可以不传一个数据类型为dict的值给它),它将其转换成 json 格式的数据。
②.入参【encoder】:默认值为django.core.serializers.json.DjangoJSONEncoder或DjangoJSONEncoder,用于序列化data。(关于序列化的更多知识点可以百度搜索json序列化进行学习,目前只需要了解要这么用即可) ③.入参【safe】 : 默认值为True。如果值设置为False,表示可以传递任何对象(比如list/tuple/dict)进行序列化;如果值设置为True,而第一个参数data的值不是dict对象,将抛出一个TypeError。
④.入参【json_dumps_params】:默认值为None。在django1.9版本中新增的入参,可以传递一个python里的json库里的json.dump() 方法处理后的对象给该入参当入参值,用于生成一个响应。(了解即可)
三、【方案1:使用方法serializers】的具体方案实现流程
1、第一步:先编写相关代码内容的视图函数
相关代码:
from django.core import serializers
import json
from django.http import JsonResponse
def search_person(request):
# 第一种返回给前端页面的是json数据类型的方案:使用【serialize】
data = {}
a = Person.objects.all()
b = serializers.serialize("json", a)
print(type(b))
print(b)
print("================================分割线1===================================")
c = json.load(b)
print(type(c))
print(c)
print("================================分割线2===================================")
data["result"] = c
print(data["result"])
print(data)
print("================================分割线3===================================")
d = JsonResponse(data, json_dumps_params={"ensure_ascii": False})
print(type(d))
print(d)
print(d.content)
return JsonResponse(data, json_dumps_params={"ensure_ascii": False})
2、第二步:在任一浏览器访问该网址【http://127.0.0.1:8000/search_person】,查看结果页面的数据展示
3、第三步:可以把接口返回值拿到该网站【https://www.json.cn/】进行解析和格式化,便于直观查看
4、第四步:查看打印的日志信息,看是否符合预期结果
四、【方案2:使用方法model_to_dict 】的具体方案实现流程
1、第一步:先编写相关代码内容的视图函数
相关代码:
From django.forms import model_to_dict
def search_person(request):
# 第二种返回给前端页面的是json数据类型的数据方案:【方案2:使用方法model_to_dict】
res = Person.objects.all()
json_list = []
for i in res:
json_dict = model_to_dict(i)
json_list.append(json_dict)
print(json_list)
return JsonResponse(json_list, safe=False, json_dumps_params={"ensure_ascii": False})
2、第二步:在任一浏览器访问该网址【http://127.0.0.1:8000/search_person】,查看结果页面的数据展示
3、第三步:查看打印的日志信息,看是否符合预期结果
五、【方案3:使用方法value跟方法list结合】的具体方案实现流程
1、第一步:先编写相关代码内容的视图函数
相关代码:
def search_person(request):
# 第三种返回给前端页面的是json数据类型的数据方案:【方案3:使用方法value()跟方法list结合】
res = Person.objects.all().values()
print(type(res))
print(res)
print("================================分割线1===================================")
res = list(res)
print(type(res))
data = {"result": res}
print(data)
print("================================分割线2===================================")
return JsonResponse(data, json_dumps_params={"ensure_ascii": False})
2、第二步:在任一浏览器访问该网址【http://127.0.0.1:8000/search_person】,查看结果页面的数据展示
3、第三步:查看打印的日志信息,看是否符合预期结果
细节:
①.【方案3:使用方法value()跟方法list结合】是主流常用的方案,后续我们进行平台开发时尽量选择这个方案3即可。