python进阶——django学习之Model
Django对各种数据库提供了很好的支持,Django为这些数据库提供了同一的调用API,可以不同的业务需求选择不同的数据库
前言
- 基础流程
- 配置数据库(查看基础流程)
- 定义模型类
- 生成迁移文件
- 执行迁移生成数据表
- 使用模型类进行增删改查(CRUD)
- ORM:Object-Relational-Mapping,即对象-关系-映射
- 根据对象的类型生成表结构
- 将对象、列表的操作转换为SQL语句
- 将查询到的结果转换为对象或者列表
定义模型
模型、属性、表、字段间的关系——一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段
定义属性
概述
- django根据属性的类型确定一下信息
- 当前选择的数据库支持字段的类型
- 渲染管理表单时使用的默认html控件
- 在管理站点最低限度的验证
- django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
- 属性命名限制
- 不能是python保留关键字
- 由于django的查询方式,不允许使用连续的下划线
库
- 定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中
- 使用方式
- 导入from django.db import models
- 通过models.Field创建字段类型的对象,赋值给属性
逻辑删除
- 对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,default = False
字段类型
- AutoField
一个根据实际ID自动增长的IntegerField,通常不指定,如果不指定,一个主键字段将自动添加到模型中
- CharField(max_length=字符长度)
字符串,默认的表单样式是TextInput
- TextField
大文本字段,一般超过4000使用,默认的表单控件是Textarea
- IntegerField
整数
- DecimalField(max_digits=None, decimal_places=None)
- 使用python的Decimal实例表示的十进制浮点数
- 参数说明
DecimalField.max_digits——位数总数
DecimalField.decimal_places——小数点后的数字位数
- FloatField
用python的float实例来表示浮点数
- BooleanField
true/false字段,此字段的默认表单控件是CheckboxInput
- NullBooleanField
支持null、true、false三种值
- DateField(autu_now=False, auto_now_add=False)
- 使用python的datetime.date实例表示的日期
- 参数说明
DateField.autu_now
每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是使用当前日期,默认为False
DateField.auto_now_add
当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前时间,默认为False
(1)说明
该字段默认对应的表单控件是一个TextInput,在管理员站点添加了一个JavaScript写的日历控件,和一个“Today”的快捷按钮,包含了一个额外的invalid_date错误消息键
(2)注意
auto_now_add,autu_now,and default这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果
- TimeField(autu_now=False, auto_now_add=False)
使用python的datetime.time实例表示的时间,参数同DateField
- DateTimeField(autu_now=False, auto_now_add=False)
使用python的datetime.datetime实例表示的日期和时间,参数同DateField
- FileField
一个上传文件的字段
- ImageField
继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项
- 概述
- 通过字段选项,可以实现对字段的约束
- 在字段对象时通过关键字参数指定
字段名 概述 null 如果为True,Django将空值以NULL存储到数据库中,默认是False blank 如果为True,则该字段允许为空白,默认值是False 注意:null是数据库范畴的概念,blank是表单验证范畴 db_column 字段的名称,如果未指定,则使用属性的名称 db_index 若值为True,则在表中会为此字段创建索引 default 默认值 primary_key 若为True,则该字段会成为模型的主键字段 unique 如果为True,则字段在表中必须有唯一值 关系
- 分类
ForeignKey:一对多,将字段定义在多的端中
ManyToManyField:多对多,将字段定义在两端中
OneToOneField:一对一,将字段定义在任意一端中
- 用一访问多
格式:对象.模型类小写_set
示例:grade.students_set
- 用一访问一
格式:对象.模型类小写
示例:grade.students
- 访问id
格式:对象.属性_id
示例:student.sgrade_id
创建模型类
# 创建模型类 class Students(models.Model): s_name = models.CharField(max_length=16) # 昵称 s_age = models.IntegerField() # 年龄 s_gender = models.NullBooleanField(default=False) # 性别 s_grade = models.IntegerField() # 班级 s_is_delete = models.BooleanField(default=False) # 是否删除
元选项
- 在模型类中定义Meta类,用于设置元信息,可能会有以下属性
- db_table——定义数据表明,推荐使用小写字母数据表名默认为项目小写_类名小写,db_table = “”
- ordering——对象的默认排序字段,获取对象的列表时使用,ordering = []
ordering = ['id']——升序
ordering = ['-id']——降序
模型成员
类属性
- objects
- Manager类型的一个对象,作用是与数据库进行交互
- 当定义模型类时没有指定管理器,则django为模型创建一个名为objects的管理器
- 自定义管理器
- 格式:管理器名 = models.Manager()
- 当为模型指定模型管理器,django就不再为模型类生成objects管理器
- 自定义管理器Manager类
- 模型管理器是django的模型与数据库进行交互的接口,一个模型可以有多个模型管理器
- 作用
(1)向管理器类中添加额外的方法
(2)修改管理器返回的原始查询集——重写get_queryset()方法
# 代码示例 class StudentsManager(models.Manager): # 重写方法 def get_queryset(self): return super(StudentsManager, self).get_queryset() .filter(s_is_delete=False) class Students(models.Model): # 自定义管理器Manager类 stu_obj = StudentsManager() ..... .....
创建对象
- 目的
在数据库中添加数据
- 当创建对象时,django不会对数据库进行读写操作,当调用save()方法时才与数据库交互,将对象保存到数据库表中
- 注意:__init__方法已经在父类models.Model中使用,在自定义的模型中无法使用
- 方法
在模型类中添加一个类方法
# 代码示例 class Students(models.Model): # 在模型类中添加一个类方法 @classmethod def create_student(cls, name, age, gender, grade, is_delete=False): stu = cls(s_name = name, s_age = age, s_gender = gender, s_grade = grade, s_is_delete = is_delete) return stu s_name = models.CharField(max_length=16) # 昵称 s_age = models.IntegerField() # 年龄 s_gender = models.NullBooleanField(default=False) # 性别 s_grade = models.IntegerField() # 班级 s_is_delete = models.BooleanField(default=False) # 是否删除
在自定义管理器类中添加一个方法
# 代码示例 class StudentsManager(models.Manager): # 重写方法 def get_queryset(self): return super(StudentsManager, self).get_queryset() .filter(s_is_delete=False) # 在自定义管理器类中添加一个方法 def create_student(self, name, age, gender, grade, is_delete=False): """ 调用格式:类名.管理器名.create_student(...) 示例:Students.stu_obj.create_student(...) """ stu = self.model() # 创建调用该方法的类的对象 stu.s_name = name stu.s_age = age stu.s_gender = gender stu.s_grade = grade stu.s_is_delete = is_delete return stu class Students(models.Model): # 自定义管理器Manager类 stu_obj = StudentsManager() s_name = models.CharField(max_length=16) # 昵称 s_age = models.IntegerField() # 年龄 s_gender = models.NullBooleanField(default=False) # 性别 s_grade = models.IntegerField() # 班级 s_is_delete = models.BooleanField(default=False) # 是否删除
模型查询
概述
- 查询集:表示从数据库中获取的对象集合
- 查询集可以有多个过滤器
- 过滤器就是一个函数,基于所给的参数限制查询集结果
- 从SQL的角度来说,查询集与select等价,过滤器与where等价
查询集
- 在管理器上调用过滤器方法返回查询集
- 查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用
- 惰性执行:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据
- 直接访问数据的情况
- 迭代
- 序列化
- 与if合用
- 返回查询集的方法称为过滤器
过滤器
概述 使用方法 all() 返回查询集中的所有数据 filter() 返回符合条件的数据 filter(条件1, 条件2, ...) filter(条件1).filter(条件2).... exclude() 过滤符合条件的数据 order_by() 排序 values() 返回一个列表,一条数据就是一个对象(字典)
- 返回单个数据
过滤器 概述 get() 返回一个满足条件的对象
注意:
(1)如果没有找到符合条件的对象,会引发"模型类.DoesNotExist"异常
(2)如果找到多个对象,会引发"模型类.MultipleObjectReturn"异常
count()
返回当前查询集中的对象个数 first() 返回查询集中的第一个对象 last() 返回查询集中的最后一个对象 exists() 判断查询集中是否有数据,如果有数据返回True
- 限制查询集
- 查询集返回列表,可以使用下标的方法进行限制(切片),等同于SQL中的limit
- 注意:下标不能为负数
- 查询集的缓存
- 概述
(1)每个查询集都包含一个缓存,来最小化的对数据库访问
(2)在新建的查询集中,缓存首次为空,第一次对查询集求值,会发送数据缓存,django会将查询出来的数据做一个缓存,并返回查询结构,有以后的查询直接使用查询集的缓存
- 字段查询
- 概述
(1)实现SQL中的where语句,作为方法filter()、exclude()、get()的参数
(2)语法:属性名称__比较运算符=值
(3)外键:属性名_id
(4)转义:SQL语句中的like使用%是为了匹配占位,匹配数据中的%时用"where like \%"
filter(s_name__contains='%')
比较运算符
比较运算符 概述 示例 exact 判断,大小写敏感 filter(is_delete=False) contains 是否包含,大小写敏感 filter(s_name__contains='林') startswith 以value开头 filter(s_name__startswith='林') endswith 以value结尾 filter(s_name__endswith='啊') 以上四个在前面加上"i"表示不区分大小写,即iexact、icontains、istartswith、iendswith
isnull 是否为空 filter(s_name__isnull=False) isnotnull filter(s_name__isnotnull=False) in 是否包含在范围内 filter(s_name__in=['小明', '小东', '李华', '康康', '乐乐']) gt 大于 filter(s_age__gt=15) gte 大于等于 filter(s_age__gte=15) lt 小于 filter(s_age__lt=15) lte 小于等于 filter(s_age__lte=15) year
month
day
week_day
hour
minute
second日期时间选择器 filter(time__year=2011)
filter(time__month=2)
filter(time__day=10)跨关联查询 处理join查询 语法:模型类名__属性名__比较运算符 查询快捷 pk——代表主键 聚合函数
概述:使用aggregate()函数返回聚合函数的值
聚合函数 概述 示例 Avg 平均值 aggregate(Avg('s_age')) Count 对象数量 aggregate(Count('s_name')) Max 最大值 aggregate(Max('s_age')) Min 最小值 aggregate(Min('s_age')) Sum 求和 aggregate(Sum('s_age')) F对象
- 可以使模型的A属性与B属性进行比较
示例:filter(boy_num__gt=F('girl_num'))
- 支持F对象的算术运算
示例:filter(boy_num__gt=F('girl_num')+20)
Q对象
- 概述:过滤器的方法中的关键字参数,条件为And模式
- OR查询示例:filter(Q(pk__lt=3) | Q(pk__gt=5))
- 只有一个Q对象时仅用于匹配,即filter(Q(pk__lt=3))等同于filter(pk__lt=3)
- filter(~Q(pk__lt=3)),加"~"为取反