Django ValuesQuerySet转json方式


Posted in Python onMarch 16, 2020

在使用ValuesQuerySet存放查询结果时,有时需要转为json,但并不能直接使用json.dumps()直接转,而是需要经过下面一个步骤:

result_set = Apple.objects.all().values()

print type(result_set)
data_list = result_set[:] # queryset转为list
print type(data_list)

output:

<class 'django.db.models.query.ValuesQuerySet'>
<type 'list'>

经过转换之后,data_list可以使用json.dumps()转为json;

为什么要有ValuesQuerySet?

查询内容直接转为字典形式,方便后续使用;

可以指定查询哪一列;例如Apple.objects.all().values(‘id'),只会查询表中的id这一列;

补充知识:Python对象转json【包括嵌套对象转json,django的model转json】

背景:

给app写接口时经常会遇到将一个model转为json返回。

问题:

网上也有类似方法,只是搜索结果多少有些问题,总是搜了好一会儿才找到合适的方法,另外,网上更多集中的只是简单些的对象,对于复杂的对象,还是不容易找到好的方式。

方案(python3.6):

1对象转json:

model类

class People():
  def __init__(self, name, age, pet):
    self.name = name
    self.age = age
    self.pet = pet
class Pet():
  def __init__(self, pet_type, pet_name):
    self.pet_type = pet_type
    self.pet_name = pet_name

将Pet对象转json:

import json
def pet2json():
  pet = Pet('Cat', 'Lili')
  js = json.dumps(pet.__dict__)
  print(js)

结果:

{“pet_type”: “Cat”, “pet_name”: “Lili”}

小结:充分利用了Python对象的dict方法,Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案。dict是用来存储对象属性的一个字典,其键为属性名,值为属性的值。dict可直接json化。

2嵌套对象转json:

刚才的People类可看做是嵌套类,即有一个属性是另一个类的实例,此时,若用上面的方法来json化Person对象,会有问题,如下【错误】:

def simple_person():
  pet = Pet('Cat', 'Lili')
  p = People('Xiaoming', 12,pet)
  json_data = json.dumps(p.__dict__)
  print(json_data)

结果:

报异常TypeError: Object of type ‘Pet' is not JSON serializable

原因:json只能针对JSON serializable对象直接进行json化,而一般只有内置的类型,比如string,int,list和dict等才能直接序列化,代码中p._ dict _是个dict类型,但是其pet属性仍是自定义的类,是不能直接json化的。

解决方式【正确】:

def simple_person():
  pet = Pet('Cat', 'Lili')
  p = People('Xiaoming', 12,pet.__dict__)
  json_data = json.dumps(p.__dict__)
  print(json_data)

结果:

{“name”: “Xiaoming”, “age”: 12, “pet”: {“pet_type”: “Cat”, “pet_name”: “Lili”}}

小结:充分利用_ dict _方法。

3django的model转json:

首先有个model类

class Person(models.Model):
  name = models.CharField(max_length=50, null=False)
  age = models.IntegerField(default=0)
  pid = models.CharField(max_length=20, unique=True)
  gender = models.IntegerField(default=0)

针对该Person类,有两种常见情况需要提供其json:

1:根据pid查询person记录;

2:根据某些条件,查询一些person记录。

此时数据库里已经插入了一些数据

这里要提一下网上比较常见的一种方式,需要用到django.core.serializers,这个类的serialize(format, queryset, **options)方法,很明显,这个方式只能作用与queryset格式,并且通过例子(不再列出),得到的结果类似这种 [{“model”: “polls.person”, “pk”: 2, “fields”: {“name”: “Cysion”, “age”: 29, “pid”: “3708261989”, “gender”: 0}}],出现了model,pk,field等属性,不但用不到(对app来说),而且还增加了其它属性的使用复杂度。这个在官网的说明文档里也是如此处理,但是作者并不推荐。

方案:

我们还是使用_ dict _这个利器,首先,我们根据pid获得一个Person对象,然后利用dict方法打印看看结果(错误)

req_pid=3708262007//request中得到
    try:
      rt = Person.objects.get(pid=req_pid)
      print(rt.__dict__)
      return HttpResponse(json.dumps(rt.__dict__),content_type='application/json')
      # return JsonResponse(rt.__dict__, safe=False)//另一种方式
    except:
      return JsonResponse(datalogic.get_comon_resp(1, '没有查询到对应数据'))

结果是:

print结果{‘_state': < django.db.models.base.ModelState object at 0x0000000004C80860 >, ‘id': 17, ‘name': ‘zhaoliu', ‘age': 10, ‘pid': ‘3708262007', ‘gender': 1}

啧啧,又多了些属性,特别是这个_state,是不能序列化的,所以上述并不能直接返回想要的结果。

解决方式:既然_state无用,且影响了结果,那我们直接临时除去,不就返回了想要的结果吗(正确)。

req_pid = request.POST.get('pid')
    try:
      rt = Person.objects.get(pid=req_pid)
      rt.__dict__.pop("_state")
      return JsonResponse(rt.__dict__, safe=False)
    except:
      return JsonResponse(datalogic.get_comon_resp(1, '没有查询到对应数据'))

接口返回结果是:

{
  "id": 17,
  "name": "zhaoliu",
  "age": 10,
  "pid": "3708262007",
  "gender": 1
}

正是客户端需要的。

最后,是返回列表的,比如需要这种结果

{
  "code": 0,
  "msg": "成功",
  "data": [
    {
      "id": 2,
      "name": "Cysion",
      "age": 29,
      "pid": "3708261989",
      "gender": 0
    },
    {
      "id": 11,
      "name": "Sophia",
      "age": 22,
      "pid": "3708261998",
      "gender": 1
    },
    {
      "id": 15,
      "name": "lisi",
      "age": 13,
      "pid": "3708262005",
      "gender": 0
    }
  ]
}

实现思路同上面类似,首先数据库查询后得到QuerySet,其不能直接json化(通过serializer得到的不好看,也不好处理,大量的属性处理还比较费劲),需要将其遍历得到每个对象,然后将其属性字典加入到list中,最后将其添加到通用dict中

pers = Person.objects.all()
result = {"code":0,"msg":"成功"}
L = []
for p in pers:
  p.__dict__.pop("_state")//需要除去,否则不能json化
  L.append(p.__dict__)//注意,实际是个json拼接的过程,不能直接添加对象
result ['data'] = L

这个时候result 就是个可以直接json化的对象了,通过

return JsonResponse(result, safe=False)

可以返回上面需要的结果。

主要提供了思路,详细代码就不提供了。

以上这篇Django ValuesQuerySet转json方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现的简单窗口倒计时界面实例
May 05 Python
Python实现保证只能运行一个脚本实例
Jun 24 Python
django如何连接已存在数据的数据库
Aug 14 Python
python 对给定可迭代集合统计出现频率,并排序的方法
Oct 18 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
Jan 04 Python
python 设置xlabel,ylabel 坐标轴字体大小,字体类型
Jul 23 Python
如何基于Python按行合并两个txt
Nov 03 Python
Django框架请求生命周期实现原理
Nov 13 Python
Python 列表反转显示的四种方法
Nov 16 Python
Matplotlib绘制条形图的方法你知道吗
Mar 21 Python
Python批量解压&压缩文件夹的示例代码
Apr 04 Python
pytorch实现加载保存查看checkpoint文件
Jul 15 Python
Django 再谈一谈json序列化
Mar 16 #Python
django实现将后台model对象转换成json对象并传递给前端jquery
Mar 16 #Python
Python读写操作csv和excle文件代码实例
Mar 16 #Python
django模型动态修改参数,增加 filter 字段的方式
Mar 16 #Python
Python Django2 model 查询介绍(条件、范围、模糊查询)
Mar 16 #Python
python高阶函数map()和reduce()实例解析
Mar 16 #Python
Django models filter筛选条件详解
Mar 16 #Python
You might like
PHP include_path设置技巧分享
2011/07/03 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
PHP 数组基本操作小结(推荐)
2016/06/13 PHP
php7 参数、整形及字符串处理机制修改实例分析
2020/05/25 PHP
JavaScript关于select的相关操作说明
2010/01/13 Javascript
Jquery创建层显示标题和内容且随鼠标移动而移动
2014/01/26 Javascript
Javascript进制转换实例分析
2015/05/14 Javascript
jQuery实现网站添加高亮突出显示效果的方法
2015/06/26 Javascript
JavaScript中利用各种循环进行遍历的方式总结
2015/11/10 Javascript
浅谈JS原生Ajax,GET和POST
2016/06/08 Javascript
javascript中setAttribute兼容性用法分析
2016/12/12 Javascript
Vue.js双向绑定操作技巧(初级入门)
2016/12/27 Javascript
vue实现长图垂直居上 vue实现短图垂直居中
2017/10/18 Javascript
JS中实现浅拷贝和深拷贝的代码详解
2019/06/05 Javascript
Vue formData实现图片上传
2019/08/20 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
2020/11/07 Javascript
使用python检测主机存活端口及检查存活主机
2015/10/12 Python
Python3 处理JSON的实例详解
2017/10/29 Python
Python内置函数 next的具体使用方法
2017/11/24 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
kafka-python 获取topic lag值方式
2019/12/23 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
python 用opencv实现霍夫线变换
2020/11/27 Python
python 调整图片亮度的示例
2020/12/03 Python
pip 20.3 新版本发布!即将抛弃 Python 2.x(推荐)
2020/12/16 Python
canvas实现按住鼠标移动绘制出轨迹的示例代码
2018/02/05 HTML / CSS
Auchan Direct波兰:欧尚在线杂货店
2016/10/19 全球购物
美国半成品食材配送服务商:Home Chef
2018/01/25 全球购物
写好自荐信的要点
2013/11/06 职场文书
工作中个人的自我评价
2013/12/31 职场文书
《荷花》教学反思
2014/04/16 职场文书
好听的队名和口号
2014/06/09 职场文书
卫生院艾滋病宣传活动小结
2014/07/09 职场文书
全国法制宣传日活动总结2014
2014/11/01 职场文书
计算机实训报告总结
2014/11/05 职场文书
离婚民事起诉状
2015/08/03 职场文书