QuerySet
Django 的 ORM(Object-Relational Mapping,对象-关系映射)是一个非常强大的工具,它帮助你管理和查询数据库。ORM 能够让你使用Python(或其他编程语言)来操作数据库,就像你在操作Python对象一样。ORM用到三个类:Manager、QuerySet、Model。
从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet。
Django的ORM通过Model的objects属性提供各种数据操的接口(API),并通过 Model.objects 方法返回QuerySet,生产符合查询条件的列表,列表中包含多个 Instance。
QuerySet 的正式定义
复制 class QuerySet ( model = None , query = None , using = None )[ source ]
QuerySet 的两大特色
(1) 惰性:若这个对象中包含了需要的数据且需要使用时,它会去DB中获取数据,否则不会获取。 比如说在内部,创建、 过滤、切片和传递一个QuerySet,而没有进行真正的数据执行,不会真实操作数据库,被称为惰性。(2)缓存使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。
QuerySet 的 API 方法
filter()(**kwargs)
用于返回符合条件的所有数据
get()
方法与 filter()
的作用类似,用于返回符合条件的单个对象但是可能会返回多个值
update()
:将符合条件的所有对象的某个字段值进行更新
create()
是 save()
方法的快捷方式,用于创建并保存一个新的对象
order_by()
:对返回的对象进行排序,默认为升序。降序则在字段名前面加负号
values()
:用来指定提取的数据中需要提取哪些字段
调用方法是:模型名.objects.方法名
比如views.py中的代码示例
复制 queryset = GoodsCategory . objects . all ()
category , created = GoodsCategory . objects . get_or_create (name = category_name)
goods = Goods . objects . filter (category = goods_category)
Instance
Instance指的是一个 Django 模型的单个实例,也就是数据库中的一行数据。相比于 QuerySet(查询集合),它是针对单个对象的操作,用于创建、更新或者删除单个模型实例。
QuerySet 适用于需要查找多个对象或进行聚合操作的场景,而 Instance 适用于单独对象的创建、修改和删除操作。
创建一个对象
复制 Obj = Model (attr1 = val1, attr2 = val2) ,Obj . save ()
更新一个对象
复制 Obj = Model . objects . get (id = xxx) ,Obj . attr1 = val1,Obj . save ()
删除一个对象
复制 Obj = Model . objects . get (id = xxx) ,Obj . delete ()
操作演示
打开shell
我们使用 shell 来熟悉 QuerySet 和 Instance 的操作
ctrl + `
打开 vscode
终端,执行进入 erp
目录,打开 shell
复制 python manage.py shell
(ybw) PS D:\星球项目\django后端开发> cd .\erp\
(ybw) PS D:\星球项目\django后端开发\erp> python .\manage.py shell
(ybw) PS D:\星球项目\django后端开发\erp> python .\manage.py shell
Python 3.11.2 | packaged by Anaconda, Inc. | (main, Mar 27 2023, 23:35:04) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.13.2 -- An enhanced Interactive Python. Type '?' for help.
In [1]:
导入 models.py 中的2个类
复制 from apps . models import *
models.py 中有2个类
GoodsCategory 和 Goods
复制 ## 产品分类表
class GoodsCategory ( Model ):
"""产品分类"""
name = CharField (max_length = 64 , verbose_name = '分类名称' )
remark = CharField (max_length = 64 , null = True , verbose_name = '备注' , blank = True )
## 产品表
class Goods ( Model ):
"""产品"""
# 外键
category = ForeignKey (GoodsCategory, on_delete = SET_NULL, related_name = 'goods_set' , null = True , verbose_name = '产品分类' ,
blank = True , )
# on_delete
number = CharField (max_length = 32 , verbose_name = '产品编号' )
name = CharField (max_length = 64 , verbose_name = '产品名称' )
barcode = CharField (max_length = 32 , null = True , blank = True , verbose_name = '条码' )
spec = CharField (max_length = 64 , null = True , blank = True , verbose_name = '规格' )
shelf_life_days = IntegerField (null = True , verbose_name = '保质期天数' )
purchase_price = FloatField (default = 0 , verbose_name = '采购价' )
retail_price = FloatField (default = 0 , verbose_name = '零售价' )
remark = CharField (max_length = 128 , null = True , blank = True , verbose_name = '备注' )
QuerySet 和 Instance 演示
QuerySet 示例
all() :返回全部对象
复制 In [ 2 ]: GoodsCategory . objects . all ()
Out [ 2 ]: < QuerySet [ < GoodsCategory : 水果 > , < GoodsCategory : 动物 > , < GoodsCategory : 电脑 > , < GoodsCategory : 眼镜 > , < GoodsCategory : 衣服 > , < GoodsCategory : 皮鞋 > , < GoodsCategory : 茶壶 > ] >
In [ 6 ]: Goods . objects . all ()
Out [ 6 ]: < QuerySet [ < Goods : 苹果 > , < Goods : 桃子 > , < Goods : 猴子 > , < Goods : 大象 > ] >
这里分别显示了GoodsCategory
和Goods
的全部对象
values():显示更详细信息
复制 In [ 4 ]: GoodsCategory . objects . values ()
Out [ 4 ]: < QuerySet [{ 'id' : 2 , 'name' : '水果' , 'remark' : '水果' }, { 'id' : 3 , 'name' : '动物' , 'remark' : '动物' }, { 'id' : 9 , 'name' : '电脑' , 'remark' : None }, { 'id' : 13 , 'name' : '眼镜' , 'remark' : None }, { 'id' : 14 , 'name' : '衣服' , 'remark' : '衣服' }, { 'id' : 15 , 'name' : '皮鞋' , 'remark' : '皮鞋' }, { 'id' : 16 , 'name' : '茶壶' , 'remark' : None }] >
In [ 7 ]: Goods . objects . values ()
Out[7]: <QuerySet [{'id': 1, 'category_id': 2, 'number': '1', 'name': '苹果', 'barcode': None, 'spec': None, 'shelf_life_days': 10, 'purchase_price': 3.0, 'retail_price': 5.0, 'remark': None}, {'id': 2, 'category_id': 2, 'number': '2', 'name': '桃子', 'barcode': None, 'spec': None, 'shelf_life_days': 10, 'purchase_price': 4.0, 'retail_price': 6.0, 'remark': None}, {'id': 3, 'category_id': 3, 'number': '3', 'name': '猴子', 'barcode': None, 'spec': None, 'shelf_life_days': 40, 'purchase_price': 60.0, 'retail_price': 100.0, 'remark': None}, {'id': 4, 'category_id': 3, 'number': '4', 'name': '大象', 'barcode': None, 'spec': None, 'shelf_life_days': 200, 'purchase_price': 100.0, 'retail_price': 200.0, 'remark': None}]>
可以看出GoodsCategory
包含id
,name
,remark
3个特征
Goods
包含id
,category_id
,number
,name
,barcode
,spec
,shelf_life_days
,purchase_price
,retail_price
,remark
10个特征
复制 In [ 16 ]: Goods . objects . values ( 'number' , 'name' , 'retail_price' )
Out [ 16 ]: < QuerySet [{ 'number' : '1' , 'name' : '苹果' , 'retail_price' : 5.0 }, { 'number' : '2' , 'name' : '桃子' , 'retail_price' : 6.0 }, { 'number' : '3' , 'name' : '猴子' , 'retail_price' : 100.0 }, { 'number' : '4' , 'name' : '大象' , 'retail_price' : 200.0 }] >
只显示number
,name
,retail_price
3个特征
count():计算对象数目
复制 In [ 19 ]: GoodsCategory . objects . all (). count ()
Out [ 19 ]: 7
In [ 20 ]: Goods . objects . values (). count ()
Out [ 20 ]: 4
In [ 32 ]: queryset = GoodsCategory . objects . all ()
In [ 33 ]: queryset . count ()
Out [ 33 ]: 7
可以看出GoodsCategory
包含7个对象,Goods
包含4个对象
同时QuerySet
的结果可以赋给变量,进行后续操作
filter():筛选符合条件的对象
复制 In [ 5 ]: GoodsCategory . objects . values (). filter (remark = None )
Out [ 5 ]: < QuerySet [{ 'id' : 9 , 'name' : '电脑' , 'remark' : None }, { 'id' : 13 , 'name' : '眼镜' , 'remark' : None }, { 'id' : 16 , 'name' : '茶壶' , 'remark' : None }] >
返回remark=None
的对象
复制 In [ 18 ]: Goods . objects . values ( 'number' , 'name' , 'retail_price' ). filter (number__gt = 2 )
Out [ 18 ]: < QuerySet [{ 'number' : '3' , 'name' : '猴子' , 'retail_price' : 100.0 }, { 'number' : '4' , 'name' : '大象' , 'retail_price' : 200.0 }] >
返回number > 2
的对象
复制 In [ 23 ]: Goods . objects . values ( 'number' , 'name' , 'retail_price' ). filter (number__gt = 1 , retail_price__lt = 150 )
Out [ 23 ]: < QuerySet [{ 'number' : '2' , 'name' : '桃子' , 'retail_price' : 6.0 }, { 'number' : '3' , 'name' : '猴子' , 'retail_price' : 100.0 }] >
返回 number > 1
以及 retail_price < 150
的对象,即 filter
可以多个条件联合使用
exclude():排除符合条件的对象
复制 In [ 21 ]: GoodsCategory . objects . values (). exclude (remark = None )
Out [ 21 ]: < QuerySet [{ 'id' : 2 , 'name' : '水果' , 'remark' : '水果' }, { 'id' : 3 , 'name' : '动物' , 'remark' : '动物' }, { 'id' : 14 , 'name' : '衣服' , 'remark' : '衣服' }, { 'id' : 15 , 'name' : '皮鞋' , 'remark' : '皮鞋' }] >
去除remark=None
的对象,即筛选出remark != None
的对象
update():修改数据并保存
复制 In [ 25 ]: GoodsCategory . objects . filter (id = 13 ). update (remark = '眼镜' )
Out [ 25 ]: 1
In [ 27 ]: GoodsCategory . objects . values (). filter (id = 13 )
Out [ 27 ]: < QuerySet [{ 'id' : 13 , 'name' : '眼镜' , 'remark' : '眼镜' }] >
将GoodsCategory
的id=13
的对象的 remark
改成眼镜
delete():删除对象
复制 In [ 28 ]: GoodsCategory . objects . filter (name = '动物' ). delete ()
Out [ 28 ]: ( 1 , { 'apps.GoodsCategory' : 1 } )
In [ 29 ]: GoodsCategory . objects . all ()
Out [ 29 ]: < QuerySet [ < GoodsCategory : 水果 > , < GoodsCategory : 电脑 > , < GoodsCategory : 眼镜 > , < GoodsCategory : 衣服 > , < GoodsCategory : 皮鞋 > , < GoodsCategory : 茶壶 > ] >
删除name="动物"
的对象
order_by():对筛选结果排序
复制 In [ 30 ]: Goods . objects . values ( 'number' , 'name' , 'retail_price' ). order_by ( 'retail_price' )
Out [ 30 ]: < QuerySet [{ 'number' : '1' , 'name' : '苹果' , 'retail_price' : 5.0 }, { 'number' : '2' , 'name' : '桃子' , 'retail_price' : 6.0 }, { 'number' : '3' , 'name' : '猴子' , 'retail_price' : 100.0 }, { 'number' : '4' , 'name' : '大象' , 'retail_price' : 200.0 }] >
将Goods的number
,name
,retail_price
3个特征 按照retail_price
进行升序排列
复制 In [ 31 ]: Goods . objects . values ( 'number' , 'name' , 'retail_price' ). order_by ( '-retail_price' )
Out [ 31 ]: < QuerySet [{ 'number' : '4' , 'name' : '大象' , 'retail_price' : 200.0 }, { 'number' : '3' , 'name' : '猴子' , 'retail_price' : 100.0 }, { 'number' : '2' , 'name' : '桃子' , 'retail_price' : 6.0 }, { 'number' : '1' , 'name' : '苹果' , 'retail_price' : 5.0 }] >
通过添加负号,将 Goods
按照降序排列
Instance示例
get():指定一个对象
复制 In [ 42 ]: Goods . objects . get (name = '苹果' )
Out [ 42 ]: < Goods : 苹果 >
In [ 43 ]: Goods . objects . values (). get (name = '苹果' )
Out [ 43 ]:
{ 'id' : 1 ,
'category_id' : 2 ,
'number' : '1' ,
'name' : '苹果' ,
'barcode' : None ,
'spec' : None ,
'shelf_life_days' : 10 ,
'purchase_price' : 3.0 ,
'retail_price' : 5.0 ,
'remark' : None }
返回name="苹果"
的对象
修改一个对象
复制 In [ 44 ]: obj = Goods . objects . get (name = '苹果' )
In [ 45 ]: obj . purchase_price = 4.0
In [ 46 ]: obj . retail_price = 6.0
In [ 47 ]: obj . remark = '水果'
In [ 48 ]: obj . save ()
In [ 52 ]: Goods . objects . values (). get (name = '苹果' )
Out [ 52 ]:
{ 'id' : 1 ,
'category_id' : 2 ,
'number' : '1' ,
'name' : '苹果' ,
'barcode' : None ,
'spec' : None ,
'shelf_life_days' : 10 ,
'purchase_price' : 4.0 ,
'retail_price' : 6.0 ,
'remark' : '水果' }
delete():删除一个对象
复制 In [ 56 ]: GoodsCategory . objects . values ()
Out [ 56 ]: < QuerySet [{ 'id' : 2 , 'name' : '水果' , 'remark' : '水果' }, { 'id' : 9 , 'name' : '电脑' , 'remark' : None }, { 'id' : 13 , 'name' : '眼镜' , 'remark' : '眼镜' }, { 'id' : 14 , 'name' : '衣服' , 'remark' : '衣服' }, { 'id' : 15 , 'name' : '皮鞋' , 'remark' : '皮鞋' }, { 'id' : 16 , 'name' : '茶壶' , 'remark' : None }] >
In [ 58 ]: obj2 = GoodsCategory . objects . get (id = 16 )
In [ 59 ]: obj2
Out [ 59 ]: < GoodsCategory : 茶壶 >
In [ 60 ]: obj2 . delete ()
Out [ 60 ]: ( 1 , { 'apps.GoodsCategory' : 1 } )
In [ 61 ]: GoodsCategory . objects . values ()
Out [ 61 ]: < QuerySet [{ 'id' : 2 , 'name' : '水果' , 'remark' : '水果' }, { 'id' : 9 , 'name' : '电脑' , 'remark' : None }, { 'id' : 13 , 'name' : '眼镜' , 'remark' : '眼镜' }, { 'id' : 14 , 'name' : '衣服' , 'remark' : '衣服' }, { 'id' : 15 , 'name' : '皮鞋' , 'remark' : '皮鞋' }] >
删除GoodsCategory
中id=2
的对象,即name="茶壶"
的对象