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 相关文章推荐
通过C++学习Python
Jan 20 Python
Python新手实现2048小游戏
Mar 31 Python
python+selenium+autoit实现文件上传功能
Aug 23 Python
python绘制漏斗图步骤详解
Mar 04 Python
python库matplotlib绘制坐标图
Oct 18 Python
Python PyInstaller库基本使用方法分析
Dec 12 Python
pyinstaller还原python代码过程图解
Jan 08 Python
Python continue语句实例用法
Feb 06 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
Feb 14 Python
屏蔽Django admin界面添加按钮的操作
Mar 11 Python
浅析Python 抽象工厂模式的优缺点
Jul 13 Python
Django中ORM的基本使用教程
Dec 22 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
smarty section简介与用法分析
2008/10/03 PHP
php抓取并保存网站图片的实现代码
2015/10/28 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
学习ExtJS fit布局使用说明
2009/10/08 Javascript
Underscore.js 的模板功能介绍与应用
2012/12/24 Javascript
js单向链表的具体实现实例
2013/06/21 Javascript
js中通过split函数分割字符串成数组小例子
2013/09/21 Javascript
js实现特定位取反原理及示例
2014/06/30 Javascript
JavaScript驾驭网页-获取网页元素
2016/03/24 Javascript
JavaScript实现倒计时跳转页面功能【实用】
2016/12/13 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
2017/04/21 Javascript
鼠标拖动改变DIV等网页元素的大小的实现方法
2017/07/06 Javascript
JS获取填报扩展单元格控件的值的解决办法
2017/07/14 Javascript
使用Angular CLI进行Build(构建)和Serve详解
2018/03/24 Javascript
mpvue小程序循环动画开启暂停的实现方法
2019/05/15 Javascript
vue 实现cli3.0中使用proxy进行代理转发
2019/10/30 Javascript
Vue中this.$nextTick的作用及用法
2020/02/04 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
2020/08/27 Javascript
python实现rsa加密实例详解
2017/07/19 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
使用python采集Excel表中某一格数据
2020/05/14 Python
python模块如何查看
2020/06/16 Python
Selenium webdriver添加cookie实现过程详解
2020/08/12 Python
html5页面结构_动力节点Java学院整理
2017/07/10 HTML / CSS
详解HTML5中的picture元素响应式处理图片
2018/01/03 HTML / CSS
英国票务网站:Ticketmaster英国
2018/08/27 全球购物
优秀村官事迹材料
2014/01/10 职场文书
企业节能减排实施方案
2014/03/19 职场文书
护士求职自荐信范文
2014/03/19 职场文书
运输服务质量承诺书
2014/03/27 职场文书
公司车辆管理制度
2015/08/04 职场文书
小学英语教学反思范文
2016/02/15 职场文书
《灰雀》教学反思
2016/02/19 职场文书
数据库连接池
2021/04/06 MySQL