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 相关文章推荐
tensorflow构建BP神经网络的方法
Mar 12 Python
Python MySQLdb 使用utf-8 编码插入中文数据问题
Mar 13 Python
DataFrame中的object转换成float的方法
Apr 10 Python
Python PyQt4实现QQ抽屉效果
Apr 20 Python
用python写一个定时提醒程序的实现代码
Jul 22 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
在keras中实现查看其训练loss值
Jun 16 Python
python模块内置属性概念及实例
Feb 18 Python
python爬虫scrapy基本使用超详细教程
Feb 20 Python
用python批量解压带密码的压缩包
May 31 Python
如何用Python搭建gRPC服务
Jun 30 Python
人工智能深度学习OpenAI baselines的使用方法
May 20 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
一个程序下载的管理程序(二)
2006/10/09 PHP
PHP入门学习的几个不错的实例代码
2008/07/13 PHP
php用户注册页面利用js进行表单验证具体实例
2013/10/17 PHP
网页上facebook分享功能具体实现
2014/01/26 PHP
php简单检测404页面的方法示例
2019/08/23 PHP
JavaScript 对话框和状态栏使用说明
2009/10/25 Javascript
基于jQuery实现的水平和垂直居中的div窗口
2011/08/08 Javascript
js使用数组判断提交数据是否存在相同数据
2013/11/27 Javascript
jquery实现的树形目录实例
2015/06/26 Javascript
JS实现超简单的鼠标拖动效果
2015/11/02 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
2016/07/28 Javascript
详解vue前后台数据交互vue-resource文档
2017/07/19 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
详解小程序循环require之坑
2019/03/08 Javascript
[03:54]DOTA2英雄梦之声_第06期_昆卡
2014/06/23 DOTA
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
Python实现批量修改文件名实例
2015/07/08 Python
python3 图片referer防盗链的实现方法
2018/03/12 Python
python实现的MySQL增删改查操作实例小结
2018/12/19 Python
详解Python函数式编程—高阶函数
2019/03/29 Python
Python生成rsa密钥对操作示例
2019/04/26 Python
python中的&amp;&amp;及||的实现示例
2019/08/07 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
Python3标准库之functools管理函数的工具详解
2020/02/27 Python
Python如何读取、写入CSV数据
2020/07/28 Python
Python爬虫基于lxml解决数据编码乱码问题
2020/07/31 Python
3D动画《斗罗大陆》上线当日播放过亿
2021/03/16 国漫
法国家具及室内配件店:home24
2017/01/21 全球购物
英国在线玫瑰专家:InterRose
2019/12/01 全球购物
机电一体化自荐信
2013/12/10 职场文书
外国人聘用意向书
2014/04/01 职场文书
文明美德伴我成长演讲稿
2014/05/12 职场文书
九寨沟导游词
2015/02/02 职场文书
php实例化对象的实例方法
2021/11/17 PHP