Django模型
一、ORM映射转换:
第一层意思:映射
Object 对象 -- models文件中定义的模型类对象
Relation 关系 -- 关系数据库中的数据表
Mapping 映射 -- 对象和数据表的一一对应
实例对象 -- 一条完整数据记录
模型类 数据库表
类名 表名
属性 字段
字段类型 字段属性
第二层意思:转换
模型类做的一个动作 具体的sql语句
all() select* from …
在MVC框架中的Model模块中都包括ORM,对于开发人员主要带来了如下好处:
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要修改代码
只需要面向对象编程,不需要面向数据库编写代码
在MVC中Model中定义的类,通过ORM与关系型数据库中的表对应,对象的属性体现对象间的关系,这种关系也被映射到数据表中,Django框架中ORM示意图如下
二、自定义模型:
定义属性
- 默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key
- 属性命名限制
- 不能是python的保留关键字
- 不允许使用连续的下划线,这是由django的查询方式决定的定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性=models.字段类型(选项)
字段类型
- BooleanField:布尔字段,值为True或False
- CharField(max_length=字符长度):字符串
- 参数max_length表示最大字符个数
- IntegerField:整数
- DateField[auto_now=False, auto_now_add=False]):日期
选项
- null:如果为True,表示允许为空,默认值是False
- blank:如果为True,则该字段允许为空白,默认值是False
- 对比:null是数据库范畴的概念,blank是表单验证证范畴的
- default:默认值
关系字段类型
- ForeignKey:一对多,将字段定义在多的一端中
- ManyToManyField:多对多,将字段定义在两端中
- OneToOneField:一对一,将字段定义在任意一端中
- 由一到多的访问语法:
对象.模型类小写_set
例:bookinfo.heroinfo_set
- 由一到一的访问语法
对象.模型类小写
例:heroinfo.bookinfo
- 访问关联对象的id语法
对象.属性_id
例:heroinfo.book_id
元选项
- 数据表的默认名称为
<app_name>_<model_name>
例:booktest_bookinfo
- 在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字
三、模型成员
模型实例方法
- str:在将对象转换成字符串时会被调用
- save():将模型对象保存到数据表中
- delete():将模型对象从数据表中删除
管理器:
默认管理器:
默认的名称是objects
可以改名,以覆盖的形式:books= models.Manager()
注意:二者只能生存一个
自定义的管理器: books = BookInfoManager()
1、修改原始查询集,重写get_queryset()方法,更改(重写)某个特殊类型属性
2、向管理器类中添加额外的方法,如创建对象,增加一个特殊的属性
注意:自定义的管理器可以和默认管理器同时存在
四、查询集
- 两大特性
- 惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用
- 缓存:查询集的结果被存下来之后,再次查询时会使用之前缓存的数据
返回列表的过滤器如下:
- all():返回所有数据
- filter():返回满足条件的数据
- exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字
- order_by():排序
返回单个值的过滤器如下:
- get():返回单个满足条件的对象
- count():返回当前查询的总条数
- aggregate():聚合
- exists():判断查询集中是否有数据
限制查询集
- 查询集返回列表,可以使用下标的方式进行限制
- 示例:list=BookInfo.books.all()[0:2]
字段查询
- 语法如下:
- 说明:属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线,属性名称__比较运算符=值
条件运算符
- exact:表示判等
- contains:是否包含
- startswith、endswith:以指定值开头或结尾
- isnull:是否为null
- 以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith
- in:是否包含在范围内
- gt、gte、lt、lte:大于、大于等于、小于、小于等于
- 不等于使用等于的运算符,使用exclude()过滤器
- year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算
关联查询
- 语法如下:
关联模型类名小写__属性名__运算符=值
- 如果没有没有“__运算符”部分,表示等于,结果和sql中的inner join相同
- 例:查询图书,要求图书中英雄的描述包含‘八’
list =BookInfo.books.filter(heroinfo__hcontent__contains='八')
- 例:查询书名为“天龙八部”的所有英雄
list =HeroInfo.objects.filter(hbook__btitle='天龙八部')
F对象
- 之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中
- 语法如下:F(属性名)
- 例:查询阅读量大于等于评论量的图书
from django.db.models importF
...
list = BookInfo.books.filter(bread__gte=F('bcommet'))
- 可以在F()对象上使用算数运算
- 例:查询阅读量大于2倍评论量的图书
list =BookInfo.books.filter(bread__gt=F('bcommet') * 2)
Q对象
- 多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字
- 例:查询阅读量大于20,并且编号小于3的图书
list=BookInfo.books.filter(bread__gt=20,id__lt=3)
或
list=BookInfo.books.filter(bread__gt=20).filter(id__lt=3)
- 如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符
- Q对象被义在django.db.models中
- 语法如下:Q(属性名__运算符=值)
- 例:查询阅读量大于20的图书,改写为Q对象如下
from django.db.models importQ
...
list = BookInfo.books.filter(Q(bread__gt=20))
- Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或
- 例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
list =BookInfo.books.filter(Q(bread__gt=20) | Q(pk__lt=3))
- Q对象前可以使用~操作符,表示非not
- 例:查询编号不等于3的图书
list =BookInfo.books.filter(~Q(pk=3))
聚合函数
- 使用aggregate()过滤器调用聚合函数
- 聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中
- 例:查询图书的总阅读量
from django.db.models importSum
...
list = BookInfo.books.aggregate(Sum('bread'))
- 使用count时一般不使用aggregate()过滤器
- 例:查询图书总数
list = BookInfo.books.count()