ORM:Object对象,Relations关系、Mapping映射。简称:对象关系映射
优点:在Django中操作数据库就不用写原生的SQL语句,而是使用面向对象的语法和一些方法来操作数据库 缺点:代码的封装程度太高,导致的问题:执行效率下降了 ,目前可以忽略,需要自己写原生SQL语句
对象关系映射是通过面向对象的方式来操作数据库,这就需要对应的关系映射,数据中可以分为库,表,字段信息,一条条数据,而需要用面向对象的关系去对应。于是就有了下面对应关系。
数据库 ======= 面向对象模型
表 ======= 类
字段 ======= 类属性
记录 ======= 每个实例
么是ORM? 对象关系映射(Object Relational Mapping 简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 ORM框架是连接数据库的桥梁 只要提供了持久化类与表的映射关系 ORM框架在运行时就能参照映射文件的信息 把对象持久化到数据库中 么用ORM? 当我们实现一个应用程序时不用ORM 我们可能会写特别多数据访问层的代码 从数据库保存、删除、读取对象信息 而这些代码都是重复的 而使用ORM则会大大减少重复性代码 对象关系映射主要实现程序对象到关系数据库数据的映射 类映射成表 对象映射成记录 对象点属性映射成字段对应的值
事务是用户定义的一系列数据库操作,这些操作可以视为一个完整的逻辑处理工作单元。 要么全部执行,要么全部不执行,是不可分割的工作单元
为了保证数据库的正确性与一致性事务具有四个特征
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
django,ORM中提供了至少三种开启事务的方式
方式一:全局开启事务
方式二:装饰器 局部有效
方式三:with 上下文管理 局部有效
需要说明的是,这些ORM字段并非与SQL字段一一对应,有些是封装了一些逻辑功能在字段的创建、存储过程中。
对应关系
任意字段都可以设置的参数
日期字段参数
用于Admin后台管理参数
其他参数
表之间的关系由一对一、一对多、多对多来确定的
通过外键来绑定各个表字段之间的关系
OneToOneField用于一对一关系的表之间进行关联。
根据Django官方文档介绍:
A one-to-one relationship. Conceptually, this is similar to a ForeignKey with unique=True, but the “reverse” side of the relation will directly return a single object.
OneToOneField与ForeignKey加上unique=True效果基本一样,但是用OneToOneField反向关联会直接返回对象。
相反地,使用ForeignKey, 反向关联后会返回QuerySet。
例如:Book表通过ForenignKey与Publish表建立了外键
Author表通过OneToOneField与AuthorDeatil表建立了外键
两张表之间多对多的关系通常需要借助第三张表来存储,这样也更利于我们查询。而第三张表的建立有三种方式:
第一种方式:通过ORM自带的ManyToManyField自动创建第三张表
这种建立第三张表具备多个:多对多关系操作API
第二种方式:自己创建第三张表,并通过ManyToManyField指定关联
through:指定我们手动创建的中间表
through_fields:指定关联字段,设置方式通过元组,值也就是关联第三张表的哪几个字段,注意先后顺序:如果book写在前面则表示我们从Author表到中间表要通过book字段,那么就会乱套了
第三种方式:自己创建第三张表,分别通过外键关联书和作者
在Django的ORM中我们也是可以使用原生SQL来进行操作的,其实我们并不能完全依赖于ORM框架来提供给我们操作数据库的便利,因为ORM在很多语言中使用形式都会有些不同,而SQL语句则是不变的。
实例:我们不需要管是基于什么对象来执行SQL语句,查出什么字段就可以直接使用
总结:执行原生sql,跟对象类型无关了,查出什么字段,可以直接使用该字段。
ps:但是基于的不同对象执行SQL语句,得到的结果也会是不同的,有些字段数据还是用不了
Meta是Django模型类里面的一个内部类,它用于定义一些Django模型类的行为特性。
通常在里面定义变量来代表选项,而可用的选项大致包含以下几类: 1、db_table 自定义表名(通常表名都是由Django帮助我们创建的,且是由:项目_类名组合的)
2、index_together 为多个字段建立联合索引,设置方式:index_together = (‘name’,‘age’)
3、unique_together 当需要通过两个字段保持模型唯一性时使用,假设有一个 User 类,我们希望 User 的 username 和 email 两个属性的组合必须是唯一的,那么需要设置为:
unique_together 的值是一个元组的元组。为了方便起见,处理单一字段的集合时unique_together 可以是一维的元组
这样就确保了driver与restaurant字段值是唯一的
4、ordering 根据哪个字段排序,设置方式:ordering = (‘id’,)
可配置参数
例子:
聚合查询是指对一个数据表中的一个字段的数据进行部分或者全部进行统计查询,例如计算平均值、总和、最大值、最小值、个数等。
聚合查询又分为整表聚合和分组聚合
整表聚合就是不带分组的聚合查询,即将全部数据进行集中统计查询
五种聚合函数
聚合查询需要先导入聚合函数
语法:
示例
aggregate(*args,**kwargs)
aggregate()是QuerySet对象的一个终止子句,意思是说,它返回一个包含一些键值对的字典
键的名称是聚合值的标识符,值是计算出来的聚合值
键的名称是按照字段和聚合函数的名称自动生成出来的
如果你想要为聚合值指定一个名称,可以向聚合子句提供它
如果你希望生成的不止一个聚合,你可与向aggregate()子句中添加别的参数。
分组聚合就是指通过计算查询结果中的每一个对象所关联的对象集合,从而得出总计值(也可以平均值、总和等),即为查询集的每一项生成聚合
annotate()为调用的QuerySet每一个对象都生成一个独立的统计值(统计方法用聚合函数)
以字段为依据将相同的分为一类,annotate()分组关键字内写聚合函数 语法:
分组依据
values() 在 annotate() 之前则表示group by字段(分组),如果不写表示按整个表分组
分组的目的:把有相同特征的分成一组,分成一组后一般用来,统计总条数、统计平均值、求最大值等。
示例
F查询:拿到某个字段在表中具体的值
从上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量作比较,如果我们要对两个字段的值作比较,那该如何做呢?
Django提供了F()来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个model实例中两个不同字段的值。
Q查询:为了组装成 与 或 非 条件
与条件:and条件,在filter中直接写就是暗调条件
或条件:or条件
非条件:not条件
复杂逻辑:
ForeignKey属性
ManyToManyField 用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系