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之编写类之四再论继承
Oct 11 Python
python操作mongodb根据_id查询数据的实现方法
May 20 Python
Python设置Socket代理及实现远程摄像头控制的例子
Nov 13 Python
python getopt详解及简单实例
Dec 30 Python
python中OrderedDict的使用方法详解
May 05 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
使用django-guardian实现django-admin的行级权限控制的方法
Oct 30 Python
tf.concat中axis的含义与使用详解
Feb 07 Python
python爬虫---requests库的用法详解
Sep 28 Python
python hmac模块验证客户端的合法性
Nov 07 Python
python爬虫请求头的使用
Dec 01 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
Dec 29 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字符过滤函数去除字符串最后一个逗号(rtrim)
2013/03/26 PHP
Laravel解决nesting level错误和隐藏index.php的问题
2019/10/12 PHP
javascript实现面向对象类的功能书写技巧
2010/03/07 Javascript
分享9点个人认为比较重要的javascript 编程技巧
2015/04/27 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
JavaScript表单焦点自动切换代码
2016/07/24 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
Angular实现较为复杂的表格过滤,删除功能示例
2017/12/23 Javascript
详解Node 定时器
2018/02/26 Javascript
微信小程序使用wxParse解析html的方法教程
2018/07/06 Javascript
vue项目打包后怎样优雅的解决跨域
2019/05/26 Javascript
原生js实现日期选择插件
2020/05/21 Javascript
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
一个基于flask的web应用诞生 组织结构调整(7)
2017/04/11 Python
Python内置模块hashlib、hmac与uuid用法分析
2018/02/12 Python
详解Python发送email的三种方式
2018/10/18 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
使用keras和tensorflow保存为可部署的pb格式
2020/05/25 Python
python二维图制作的实例代码
2020/12/03 Python
VSCODE配置Markdown及Markdown基础语法详解
2021/01/19 Python
HTML5学习笔记之html5与传统html区别
2016/01/06 HTML / CSS
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
澳大利亚工具仓库:Tools Warehouse
2018/10/15 全球购物
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?用contains来区分是否有重复的对象。还是都不用
2013/07/30 面试题
4s客服专员岗位职责
2013/12/01 职场文书
企业消防安全制度
2014/02/02 职场文书
CAD制图人员的自荐信
2014/02/07 职场文书
我的大学四年规划书范文2014
2014/09/26 职场文书
大学生在校表现评语
2014/12/31 职场文书
2015年物业管理工作总结
2015/04/23 职场文书
一年级下册数学教学反思
2016/02/16 职场文书
《女娲补天》读后感5篇
2019/12/31 职场文书
交互式可视化js库gojs使用介绍及技巧
2022/02/18 Javascript
生命的关键成分来自太空?陨石说是的
2022/04/29 数码科技