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

标签:Django,ValuesQuerySet,json
0
投稿

猜你喜欢

  • Python搭建HTTP服务过程图解

    2023-08-08 22:11:54
  • Python如何匹配文本并在其上一行追加文本

    2022-10-19 13:16:43
  • ASP使用FSO组件生成HTML静态页面

    2007-10-15 12:19:00
  • python处理xml文件操作详解

    2021-11-10 10:31:24
  • numpy系列之数组合并(横向和纵向)

    2023-11-13 07:13:21
  • 一次Mysql update sql不当引起的生产故障记录

    2024-01-21 09:09:22
  • 小程序点餐界面添加购物车左右摆动动画

    2024-04-27 15:22:36
  • python爬虫之urllib,伪装,超时设置,异常处理的方法

    2022-07-23 23:47:10
  • python处理json数据中的中文

    2021-10-02 07:11:10
  • 基于python调用psutil模块过程解析

    2022-04-09 18:22:56
  • PHP判断密码强度的方法详解

    2023-06-14 03:00:08
  • 用vue.js组件模拟v-model指令实例方法

    2022-04-16 10:12:23
  • PyTorch中torch.matmul()函数常见用法总结

    2023-03-28 16:01:31
  • python异步实现定时任务和周期任务的方法

    2021-11-11 19:01:45
  • python进行两个表格对比的方法

    2021-12-15 20:31:57
  • python中join与os.path.join()函数实例详解

    2023-08-23 19:20:51
  • python开启摄像头以及深度学习实现目标检测方法

    2023-10-27 03:23:18
  • sqoop如何指定pg库的模式(方法详解)

    2022-09-30 02:52:47
  • python用opencv批量截取图像指定区域的方法

    2021-10-14 09:07:33
  • 网友分享:Oracle数据库开发技术经验浅谈

    2009-04-22 13:11:00
  • asp之家 网络编程 m.aspxhome.com