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读取图片EXIF信息类库介绍和使用实例
Jul 10 Python
python中正则表达式 re.findall 用法
Oct 23 Python
python将txt文档每行内容循环插入数据库的方法
Dec 28 Python
python创造虚拟环境方法总结
Mar 04 Python
浅谈Python 敏感词过滤的实现
Aug 15 Python
基于python3监控服务器状态进行邮件报警
Oct 19 Python
wxPython实现绘图小例子
Nov 19 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
Dec 04 Python
Python列表解析操作实例总结
Feb 26 Python
Keras搭建自编码器操作
Jul 03 Python
Python用来做Web开发的优势有哪些
Aug 05 Python
怎么用Python识别手势数字
Jun 07 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
rrmdir php中递归删除目录及目录下的文件
2011/05/15 PHP
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
php实现屏蔽掉黑帽SEO的搜索关键字
2015/04/15 PHP
PHP快速推送微信模板消息
2017/04/14 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
2008/11/24 Javascript
ExtJS 2.0 GridPanel基本表格简明教程
2010/05/25 Javascript
js实现运动logo图片效果及运动元素对象sportBox使用方法
2012/12/25 Javascript
window resize和scroll事件的基本优化思路
2014/04/29 Javascript
JS使用ajax方法获取指定url的head信息中指定字段值的方法
2015/03/24 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
2015/06/06 Javascript
简介JavaScript中的setDate()方法的使用
2015/06/11 Javascript
JS实现网站菜单拖拽移位效果的方法
2015/09/24 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
javaScript+turn.js实现图书翻页效果实例代码
2017/02/16 Javascript
性能优化之代码优化页面加载速度
2017/03/01 Javascript
详解Node.js利用node-git-server快速搭建git服务器
2017/09/27 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
在Python的Django框架中simple-todo工具的简单使用
2015/05/30 Python
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
python如何实现int函数的方法示例
2018/02/19 Python
python3基于OpenCV实现证件照背景替换
2018/07/18 Python
Python WSGI的深入理解
2018/08/01 Python
深入学习python多线程与GIL
2019/08/26 Python
查看keras各种网络结构各层的名字方式
2020/06/11 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
python实现简易版学生成绩管理系统
2020/06/22 Python
Python下载网易云歌单歌曲的示例代码
2020/08/12 Python
python如何对链表操作
2020/10/10 Python
python 基于wx实现音乐播放
2020/11/24 Python
FILA斐乐中国官方商城:意大利运动品牌
2017/01/25 全球购物
酒店管理专业毕业生求职自荐信
2014/04/28 职场文书
四风对照检查材料范文
2014/09/27 职场文书
python入门之算法学习
2021/04/22 Python
何时使用Map来代替普通的JS对象
2021/04/29 Javascript
MySQL数据库实验之 触发器和存储过程
2022/06/21 MySQL