一、前言
最近在项目中有个接口需要将查询的数据中部分字段合并为一个字典再返回。
之前的做法要么是先通过ORM查出数据自己单独再做处理,要么是通过数据库函数Concat将这些字段拼接为一个Json字符串进行查询,后续再做处理。跟第一种的处理方法差不多,两个都很麻烦。
但在django3.2版本,它们新增了专门的数据库函数JsonObject来处理这种需求了。
二、JSONObject说明
获取键值对列表并返回包含这些对的 JSON 对象。
例如有如下表结构,表模型名称为Student:
student 表
字段 | 描述 |
id | 学生id |
name | 学生名称 |
age | 学生年龄 |
gender | 学生性别 |
address | 家庭地址 |
想查询学生信息,并将age
、gender
、address
合并为一个键名为info的json对象:
{ "info": { "age": 16, "name": "张三", "address": "中国北京市" } }
代码可以这样写:
from django.db.models import F from django.db.models.functions import JSONObject stu_data = Student.objects.annotate( info=JSONObject(name=F('name'), age=F('age')), address=F('address')).values('info')
官方文档的例子:
三、特别说明
如果涉及多对多关系的话可能会出现类似的报错
网上的解决方案会让你将sql_mode的ONLY_FULL_GROUP_BY配置删掉
这样虽然不再报错了,但查询的数据会出现遗漏!(只会取多对多关联数据的第一条数据)
正确的做法是在查询的时候加上多对多的关联字段即可,这样就不会出现数据的遗漏了。
Django还有很多数据库函数供我们使用,当我们遇到类似的问题时,不妨先看看官方文档中:https://docs.djangoproject.com/en/3.2/ref/models/database-functions/ 是否有对应的数据库函数供我们使用,这样也避免了重复造轮子的过程。