Django ORM框架之CRUD操作
前言:上篇文章中简单记录了Django通过ORM框架中的对象与数据库中的对象映射,即如何创建模型类、定义类属性、生成迁移脚本、执行迁移脚本生成数据表等操作。本篇文章会继续记录Django通过ORM框架操作数据库中的数据,即生成数据表之后对表中数据的操作:CRUD(创建、读取(查询)、更新、删除)。
一、创建数据(C)
1、创建主表数据(无外键字段)
方式一:1)实例化模型类,根据字段定义规则传递关键字参数;
2)调用模型对象的save()方法
注意:此种方式必须要调用save方法,才会执行sql语句,将数据写入到表中
示例:在调试模式下运行,查看代码执行过程
PS:此处需要添加监听器,监测否有sql语句执行,那么如何添加该监听器呢?
1)导入django.db中的connection
2)调试模式下,在Variables中添加监听器,输入connection.queries
运行代码可见:创建模型对象project_obj后,并未监测到sql语句执行
查看tb_projects数据表中也无数据生成
执行save方法后,监听到sql语句执行,查看数据表中有数据生成
方式二:模型类名.objects.create(关键字参数)
注意:1)此种方式无需调用save方法,因为在create方法源码里实现了实例化模型类和调用save方法,并将模型对象返回
2)模型类名.objects 返回的是Manage对象,是一个管理器对象
示例:
2、创建从表数据(有外键字段,需要解决从表外键对应的主表数据如何传值)
方式一:1)获取主表模型对象
2)从表模型类名.objects.create(关键字参数, 外键名=主表模型对象)
示例:
方式二:1)获取主表模型对象的id属性值
2)从表模型类名.objects.create(关键字参数, 外键名_id=主表模型对象的id属性值)
示例:
二、读取数据(R)
1、读取多条数据
1)读取数据表中的所有数据:模型类名.objects.all()
示例:
注意:a)模型类名.objects.all() 返回的是 QuerySet 对象,QuerySet 对象中包裹着多个模型对象
b)QuerySet 对象类似list,支持正值索引取值、正值切片操作、len()方法求长度、还支持迭代(可以使用for循环对查询集进行迭代),可以使用list(QuerySet对象)将去转换为list
c)QuerySet 对象具有惰性查询的特性,即在真正'用'数据时,才会执行sql语句
d)QuerySet 对象具有链式调用特性,即filter方法可以继续调用filter方法(或all方法)
e)QuerySet 对象常用方法:
first() 获取查询集中第一条数据(即模型对象)
last() 获取查询集中最后一天数据(即模型对象)
count() 获取查询集中有多少条数据(即模型对象的个数)
exists() 判断查询集是否为空
2)读取符合条件的数据(条件查询):模型类名.objects.filter(查询条件) 或 模型类名.objects.exclude(查询条件)
** 查询条件格式:字段名__查询类型=具体值
** filter方法和exclude方法支持多种查询类型:
a)等于: 字段名__exact=具体值 或 字段名=具体值
b)大于: 字段名__gt=具体值
c)大于等于: 字段名__gte=具体值
d)小于: 字段名__lt=具体值
e)小于等于: 字段名__lte=具体值
f)包含: 字段名__contains=具体值,不忽略大小写;字段名__icontains=具体值,忽略大小写
g)以...开头: 字段名__startswith=具体值,不忽略大小写;字段名__istartswith=具体值,忽略大小写
h)以...结尾: 字段名__endswith=具体值,不忽略大小写;字段名__iendswith=具体值,忽略大小写
i)是否为空: 字段名__isnull
** filter方法与exclude方法的区别:filter方法筛选出符合条件的数据并返回;exclude方法筛选出符合条件的数据后,取补集返回。
示例:
Projects.objects.filter(id__gt=1) --> 查询id>1的数据
Projects.objects.exclude(id__gt=1) --> 查询id不大于1的数据 (即id<=1的数据)
2、读取单条数据
方式一:模型类名.objects.get(查询条件)
示例:
注意:1)如果条件无法查询出结果(即没有符合条件的数据)时,此种方式会抛出异常
2)如果条件查询出来的结果为多条时,此种方式也会抛出异常
3)使用此种方式查询时,最好使用具有唯一约束的条件去查询
4)get方法查询返回的结果是模型对象
5)一般使用get方法查询时,会使用try...catch捕获异常
方式二:模型类名.objects.filter(查询条件)
示例:
注意:1)使用filter方法查询时,如果符合查询条件的数据不存在,则返回空的QuerySet对象
2)如果符合查询条件的数据为多条,则将这些数据(模型对象)包裹到QuerySet对象中返回
另:在ORM框架中,会自动给每个模型类的主键添加一个别名pk,即使用主键查询时,可以使用pk__查询类型=具体值
3、通过从表数据获取主表数据(实际上是通过从表外键字段来获取)
1)获取从表模型对象
2)从表模型对象.外键字段名
示例:在接口表中查询id为1的接口的所属项目信息
注意:虽然从表中外键字段值存储的是主表模型对象的id,但通过“从表模型对象.外键字段名”获取的是主表模型对象
4、通过主表数据获取从表数据
1)获取主表模型对象
2)主表模型对象.从表模型类名小写_set.查询方法(get/filter/exclude/all)
示例:查询name为‘测试项目’的项目所包含的所有接口信息
注意:1)从表模型类名小写_set 是ORM框架提供给主表模型对象的默认属性,主表模型对象.从表模型类名小写_set 返回的是从表的manage对象
2)从表模型类名小写_set 可以修改,在定义外键字段时,可以指定related_name属性的值,related_name代表的是主表获取从表数据的引用名称
3)不属于多表查询(执行了多条查询语句)
5、多表查询(关联查询)
1)通过主表参数来获取从表数据:要获取的是从表的数据,所以在从表查询,查询条件为主表字段的限制条件
即:从表模型类名.objects.filter(外键名__主表字段名__查询类型=具体值)
示例:查询leader为‘ppd’的项目的所有接口信息
注意:1)外键名__ 相当于是获取主表的引用,projects__name相当于是在使用主表的name字段做过滤
2)多表关联:外键1__外键2__外键3__xx字段__查询类型=具体值
2)通过从表参数来获取主表数据:要获取的是主表数据,所以在主表查询,查询条件为从表字段的限制条件
即:主表模型类名.objects.filter(从表模型类名小写__从表字段名__查询类型=具体值)
示例:查询接口名称中包含‘登录’的所有项目信息
6、查询条件间的逻辑关系
1)'与' 关系
方式一:在同一个filter方法内部,添加多个关键字参数(查询条件),这些参数之间为'与'关系
示例:查询name中包含'2',且leader也包含'2'的项目信息
方式二:多次调用filter方法,多个filter方法的查询条件间为'与'关系
示例:
方式三:通过Q查询实现,即 模型类名.objects.filter(Q(字段名__查询类型=具体值) & Q(字段名__查询类型=具体值))
2)'或' 关系
通过Q查询实现:1)导入Q类,from django.db.models import Q
2)实例化Q对象,参数为查询条件,多个Q对象之间使用 | ,那么这些Q对象之间为'或'关系
即:模型类名.objects.filter(Q(字段名__查询类型=具体值) | Q(字段名__查询类型=具体值))
示例:查询name包含'2' 或 leader是'yxj'的项目信息
7、对查询结果排序
通过QuerySet对象(或manager对象)提供的order_by方法实现排序,默认按照指定的字段升序排序,如果字段名前加“-”,则表示降序排序
即:QuerySet对象(或manager对象).order_by('字段名1', '字段名2', ... )
示例:查询name包含'2'的项目信息,并通过name进行降序排序,再通过leader进行升序排序
三、更新数据(U)
1、更新一条数据:
方式一:通过给模型对象属性赋新值 实现数据更新
1)获取要更新数据的模型对象:模型类名.objects.get(查询条件)
2)给要修改的模型对象属性赋值:模型对象.属性 = 新值
3)调用模型对象的save方法:模型对象.save()
示例:
更新id为1的项目的name和leader信息
注意:1)从上图可看出,调用save方法执行的sql语句为完整更新,即 虽然我只给name和leader赋新值,但执行save方法后,该条数据的所有字段值都进行了更新
2)使用此种方式更新数据时,往往需要给save方法传递update_fields参数(序列类型),指定需要更新的字段名称
方式二:调用查询集对象的update方法实现
即:模型类名.objects.filter(具有唯一约束的字段条件).update(字段名='新值')
2、更新多条数据 :通过调用查询集对象的update方法实现数据更新
即:模型类名.objects.filter(查询条件).update(字段名1='新值1', 字段名2='新值2', ... )
示例:更新name含有'22'的项目的leader为'小潘达'
注意:1)update方法返回的是更新成功的数据条数
2)通过给模型对象属性赋值的方式更新数据,需要手动的调用save方法后才会执行sql语句,将更新的数据写入数据表,而update方法不需要调用save方法
四、删除数据(D)
1、删除一条数据:通过调用模型对象的delete方法实现数据删除
1)获取要删除的数据的模型对象:模型类名.objects.get(查询条件)
2)调用模型对象的delete方法:模型对象.delete()
示例:删除id为6的项目数据
2、删除多条数据:通过调用QuerySet对象的delete方法实现多条数据的删除
1)获取要删除的数据查询集对象:模型类名.objects.filter(查询条件)
2)调用查询集对象的delete方法:查询集对象.delete()
示例:删除name包含'yxj'的项目数据
总结:本篇文章记录了Django ORM框架对数据进行增删改查操作,重点和难点都在查询数据上,单表查询、多表查询都需要多多练习才能掌握其中的知识点!