Django数据库查询集数据(Queryset)转化为json,查询value和value_list的用法,json.loads和json.dumps

先简单回顾一下json和字典的区别

json字典
json是一种格式字典(dict)是一种数据结构
json是类字典的形式,里面的键必须是双引号的字符串dict字典里面的键单、双引号的字符串都可以
json的key可以是有序、重复的字典(dict)的键(key)不可重复

问题概述

我们在用Django写api从数据库获取数据时,要转成json然后才能传给前端解析。
其次,这样得到的是一张表中所有字段的值,在不需要所有字段的时候只会增大开销。后续直接封装我们需要的字段名称,而不是先获取完整查询集,再展开过滤得到我们需要的字段。

语法User.objects.filter(id=request.user.id)userInfo2 = User.objects.get(id=request.user.id)
返回类型<class ‘django.db.models.query.QuerySet’><class ‘pedfsite.models.User’>
解释获取查找参数匹配的所有对象,返回查询集获取单一唯一对象使用,返回对象

无论返回哪种一般序列化(serializers.ModelSerializer)转换成json格式用作接口data返回

      ftyName = request.GET['ftyName']
      type= request.GET['type']
      pvPanelInfo = PvPanel.objects.get(factory=factory, type=type)
      print(type(pvPanelInfo))

报错

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']
        # print(ftyName, type(pvPanelType))
        pvPanelInfo = PvPanel.objects.filter(factory=ftyName, type=pvPanelType)

方法一(最原始的方法):

        # 查询集展开为json数据
        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")
        # 查询集展开为json数据
        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  # 这就是express中的serializers
# 序列化的表格也要导入进来
from photovoltaicCalculation.models import PvPanel


# 序列化获取数据库中的数据
class PvPaneltoJSON(serializers.ModelSerializer):
    class Meta:
        depth = 1  # 序列化的深度
        model = PvPanel  # 数据表
        # fields = '__all__'    #返回所有字段
        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__控制的

# 序列化多条,需要传many=True
book_ser=BookModelSerializer(books,many=True)
book_one_ser=BookModelSerializer(book)
print(type(book_ser))
#<class 'rest_framework.serializers.ListSerializer'>
print(type(book_one_ser))
#<class 'app01.ser.BookModelSerializer'>
 
# 对象的生成--》先调用类的__new__方法,生成空对象
# 对象=类名(name=lqz),触发类的__init__()
# 类的__new__方法控制对象的生成
 
 
def __new__(cls, *args, **kwargs):
    if kwargs.pop('many', False):
        return cls.many_init(*args, **kwargs)
    # 没有传many=True,走下面,正常的对象实例化
    return super().__new__(cls, *args, **kwargs)

问题总结

json.loads()json.dumps()的区别

json.dumps和json.loads()
dict转strstr转成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),查询集是一个可迭代对象
# values 结果为字典型
books = Book.objects.filter(id__lt=6).values('number')
[{'number': '1'}, {'number': '2'}, {'number': '3'}, {'number': '4'}, {'number': '5'}]
 
# values_list 结果为元祖型
books = Book.objects.values_list('number')
[('1',), ('2',), ('3',), ('4',), ('5',)]
 
# 获取某个字段所有值2
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') #必须有order_by

先这样吧,应该还有更好的方法,欢迎留言

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值