先简单回顾一下json和字典的区别
json | 字典 |
---|
json是一种格式 | 字典(dict)是一种数据结构 | json是类字典的形式,里面的键必须是双引号的字符串 | dict字典里面的键单、双引号的字符串都可以 | json的key可以是有序、重复的 | 字典(dict)的键(key)不可重复 |
问题概述
ftyName = request.GET['ftyName']
type= request.GET['type']
pvPanelInfo = PvPanel.objects.get(factory=factory, type=type)
print(type(pvPanelInfo))
后续需要把pvPanelInfo 的<class 'django.db.models.query.QuerySet'> 格式转换成json格式
报错
pvPanelInfo 返回的数据是PvPanel object (5) 但是print(type(pvPanelInfo)) 会报如下的错误。
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type TypeError is not JSON serializable
这里出现的错误是因为用type作为变量名了,应该避免用python函数名作为变量名
问题解决
用get 获取改成filter 获取数据
ftyName = request.GET['ftyName']
pvPanelType = request.GET['type']
pvPanelInfo = PvPanel.objects.filter(factory=ftyName, type=pvPanelType)
方法一(最原始的方法):
pvPanel_data = []
for pvPanel in pvPanelInfo:
pvPanel_item = {
"factory": pvPanel.factory,
"type": pvPanel.type,
"length": pvPanel.length,
"width": pvPanel.width,
}
pvPanel_data.append(pvPanel_item)
data["data"]["pvPanelList"] = pvPanel_data
方法二(给filter后加个values):
pvPanelInfo = PvPanel.objects.filter(factory=ftyName, type=pvPanelType).values("factory","type","length","width")
pvPanel_data = []
for pvPanel in pvPanelInfo:
pvPanel_data.append(pvPanel)
data["data"]["pvPanelList"] = pvPanel_data
返回示例:
{
"factory": "宇宙牌光伏板",
"type": "WH144P6-450",
"length": 2094,
"width": 1038
}
但是这样values很长
方法三(直接按model层设置格式转换)
新建toJSon.py
from rest_framework import serializers
from photovoltaicCalculation.models import PvPanel
class PvPaneltoJSON(serializers.ModelSerializer):
class Meta:
depth = 1
model = PvPanel
fields = ["id", "factory", "type", "length", "width"]
调用
from photovoltaicCalculation.toJson import PvPaneltoJSON
pvPanel_data = PvPaneltoJSON(pvPanelInfo, many=True)
print(pvPanel_data)
data["data"]["pvPanelList"] = pvPanel_data.data
返回结果
{
"factory": "宇宙牌光伏板",
"type": "WH144P6-450",
"length": 2094,
"width": 1038
}
many=True源码分析(引用)
a. 传many=True ,跟不传many=True ,实例化的序列化器对象都不一样 b. 通过__new__控制的
book_ser=BookModelSerializer(books,many=True)
book_one_ser=BookModelSerializer(book)
print(type(book_ser))
print(type(book_one_ser))
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
问题总结
json.loads() 与json.dumps() 的区别
json.dumps | 和json.loads() |
---|
dict转str | str转成dict | json.dumps 序列化时对中文默认使用的ascii编码,string=json.dumps(data,ensure_ascii=False ) | |
Django-ORM values、values_list区别
官方链接查看 按ctrl+F搜索values
values() | values_list() |
---|
values() 得到的是一个字典形式的查询集(QuerySet ),查询集是一个可迭代对象 | values_list() 结果为元祖型 | 将QuerySet 转为list: city_list = list(cities) 再将list 序列化为json: city_json = json.dumps(city_list) | 加上flat=True ,返回的是单个值,而不是元祖 | values()得到的是一个字典形式的查询集(QuerySet),查询集是一个可迭代对象 | |
books = Book.objects.filter(id__lt=6).values('number')
[{'number': '1'}, {'number': '2'}, {'number': '3'}, {'number': '4'}, {'number': '5'}]
books = Book.objects.values_list('number')
[('1',), ('2',), ('3',), ('4',), ('5',)]
books = Book.objects.values_list('number', flat=True)
books = ['1', '2', '3', '4', '5']
models = Book.objects.filter(group=group).values('number').distinct().order_by('number')
先这样吧,应该还有更好的方法,欢迎留言
|