Django ValuesQuerySet转json方式
作者:翔云123456 发布时间:2021-12-05 07:15:34
在使用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)
可以返回上面需要的结果。
主要提供了思路,详细代码就不提供了。
来源:https://blog.csdn.net/lanyang123456/article/details/72809147
猜你喜欢
- 在使用爬虫爬取别的网站的数据的时候,如果爬取频次过快,或者因为一些别的原因,被对方网站识别出爬虫后,自己的IP地址就面临着被封杀的风险。一旦
- 每次遇到pandas的dataframe某列日期格式问题总会哉坑,下面记录一下常用时间日期函数....1、字符串转化为日期 str—>
- 循环和列表不管怎样,程序会做一些重复的事情,下面我们就用for循环打印一个列表变量。做这个练习的时候你必须自己弄懂它们的含义和作用。在使用f
- 本文主要是关于matplotlib的一些基本用法。Demoimport matplotlib.pyplot as pltimport num
- SQL(结构化查询语言)就是负责与ANSI维护的数据库交互的标准。最新的版本是SQL-99,还有一个新标准SQL-200n尚处于制定过程中。
- 1.下载PyQt官方网站:http://www.riverbankcomputing.com/software/pyqt/download5
- 问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有to
- 回顾在前面的系列章节中,我们创建了一个数据库并且学着用用户和邮件来填充,但是到现在我们还没能够植入到我们的程序中。 两章之前,我
- 1. 常用模块# 连接数据库connect()函数创建一个新的数据库连接对话并返回一个新的连接实例对象PG_CONF_123 = {
- 加上设置字符编码的方法:response.setHeader("charset","gb2312")
- 页面中header部分一般位于最上端(有时根据需要也会位于某一侧,不管它在页面中的位置如何,在XHTML代码中它总是优于其它元素先加载),内
- 从ResNet到DenseNet上图中,左边是ResNet,右边是DenseNet,它们在跨层上的主要区别是:使用相加和使用连结。最后,将这
- Python版本:3.5网上找了好多资料都没有直观的写出怎么批量执行,so,整理了一个小程序。最初是为了用Python进行单元测试,同目录下
- 首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成:数据缓存(Data Buffer)、
- 一、Golang环境安装及配置Go Modulehttps://go-zero.dev/cn/docs/prepare/golang-ins
- 有些接口参数是一个文件格式,比如fiddler 抓包参数如下显示这个接口的 form-data fiddler 显示的和不带文件参数的接口有
- 一、读取Excel中的数据安装xlrd 只能读取Excel内容pip install xlrd==1.2.0xlrd库的open_workb
- 学习总结(1)和上一讲的模型训练是类似的,只是在线性模型的基础上加个sigmoid,然后loss函数改为交叉熵BCE函数(当然也可以用其他函
- 本文实例为大家分享了Python九宫格图片生成的具体代码,供大家参考,具体内容如下利用Image类将一张图片分割成9张,发朋友圈利器,打包成
- 本篇目标抓取淘宝MM的姓名,头像,年龄抓取每一个MM的资料简介以及写真图片把每一个MM的写真图片按照文件夹保存到本地熟悉文件保存的过程&nb