Model(模型)
- 在企业开发中,我们通常都是从数据开始开发的。
- 开发流程:
- 配置数据库
- 定义模型类(一个模型类对应数据库中的一张表)
- 生成迁移文件
- 执行迁移生成数据表
- 使用模型类进行增删改查(CRUD)操作
ORM
- 对象关系映射
- 可以理解为翻译机
- 核心思想:解耦合
- 将业务逻辑和SQL进行了解耦
字段类型
- 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
- 小数点后的数字位数
- DecimalField.max_digits
- FloatField
- 用python的float实例来表示的浮点数
- BooleanField
- true/false字段,此字段默认表单控制是CheckboxInput
- NullBooleanField
- 支持null、true、false三种值
- DateField([auto_now=False, auto_now_add=False])
- 使用Python的datetime.date实例表示的日期
- 参数说明
- DateField.auto_now
- 每次保存对象时,自动设置该字段为当前时间。用于"最后一次修改"的时间戳.它总是使用当前日期,默认为False。
- DateField.auto_now_add
- 当对象第一次被创建时自动设置当前时间。用于创建时间的时间戳. 它总是使用当前日期,默认为False。
- DateField.auto_now
- 说明
- 该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮.包含了一个额外的invalid_date错误消息键.
- 注意
- auto_now_add, auto_now, and default 这些设置是相互排斥的. 他们之间的任何组合将会发生错误的结果.
- TimeField
- 使用python的datetime.time实例表示的时间,参数同DateField
- DateTimeField
- 使用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.grade_id
- 格式
Django定义模型
- 重要概念:模型、表、属性、字段
- 一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段
- 定义属性见上面
- 创建模型类
- 元选项,在模型中定义Meta,用于设置元信息
class Meta: db_table = xxx # 定义数据表名,推荐使用小写字母 ordering = []
- 对象的默认排序字段,获取对象列表时使用,通常是Integer类型,升序ordering[‘id’],降序ordering[’-id’]
- 修改models后需要重新生成迁移文件:python manage.py makemigrations
- 执行迁移:python manage.py migrate
- 加函数后不用重新迁移
模型成员objects
- Django默认通过模型的objects对象实现模型数据查询
- Django有两种过滤器用于筛选记录
- filter:返回符合条件的数据集
- exclude:返回不符合筛选条件的数据集
- 多个filter和exclude可以连接在一起查询:如Person.objects.filter().filter().xxx.exclude().yyy
方法
- 对象方法
- 可以调用对象的属性,也可以调用类的属性
- 类方法
- 不能调用对象属性,只能调用类属性
- 静态方法
- 啥都不能调用。也不能获取对象属性,也不能获取类属性,只是寄生在这个类上而已
创建对象
- 目的:向数据库中添加数据
- 当创建对象时,Django不会对数据库进行读写操作,当调用save()方法时才与数据库交互,将对象保存到数据库中
- 注意:__init__已经在父类models.Model中使用,在自定义的模型中无法使用
- 创建对象方案:
- 在模型中增加类方法去创建对象
在自定义的管理器中添加方法来添加对象@classmethod def create(cls,name,age):
模型查询
- 查询集表示从数据获取的对想集合
- 查询集可以有多个过滤器
- 过滤器就是一个函数,基于所给的参数限制查询集结果
- 从SQL角度来说,查询集合和select语句等价,过滤器就像where条件
查询集和过滤器
- 在管理器上调用方法返回查询集
- 查询经过过滤器筛选后返回新的查询集,所以可以写成链式调用
- 返回查询集的方法成为过滤器
- all() 返回所有数据
- filter() 返回符合条件的数据
- exclude() 过滤掉符合条件的数据
- order_by()排序
- values() 一条数据就是一个字典,返回一个列表
返回单个数据
- get():返回一个满足条件的对象,注意处理异常
- 如果没有找到符合条件的对象,会引发模型类DoesNotExist异常
- 如果找到多个,会引发模型类MultiObjectsReturned异常
- first():返回查询集中第一个对象
- last():返回查询集中的最后一个对象
- count():返回当前查询集中的对象个数
- exists():判断查询集是否有数据,如果有数据返回True,没有反之
状态码
200-199(2xx):请求成功
300-399(3xx):转发/重定向
400-499(4xx):客户端错误
500-599(5xx):服务器错误
限制查询集和查询集的缓存
- 限制查询集,可以使用下标的方法进行限制,等同于sql中limit
- studentList = Student.objects.all()[0:5] 下标不能是负数
- 查询集的缓存,每个查询集都包含一个缓存,来最小化对数据库的访问
- 在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存。
字段查询
- 对sql中where的实现,作为方法filter(),exclude().get()的参数
- 语法:属性名称_比较运算符 = 值
- 外键:属性名_id
- 转义:like语句中使用%是为了匹配占位,匹配数据中的%
(where like '\%')
filter(sname_contains='%')
比较运算符
- exact:判断,大小写敏感,filter(isDelete=False)
- contains:是否包含,大小写敏感,filter(sname__contains=‘赵’)
- startswith,endswith:以values开头或结尾,大小写敏感
- 以上四个在运算符前加上i(ignore)就不区分大小写了
- isnull,isnotnull:是否为空,filter(sname__isnull=False)
- in:是否包含在范围内,filter(pk_in=[2,4,6,8])
- gt,gte,lt,lte:大于,等于等于,小于,小于等于 filter(sage__gt=30)
- 时间的year,month,day,week_day,hour,minute,second:filter(lasttime__year=2017)
- 查询快捷:pk:代表主键,filter(pk=1)
- 跨关系查询:
- 模型类名_属性名_比较运算符,实际上就是处理的数据库中的join
- grade=Grade.objects.filter(student__scontend__contains=‘楚人美’)
- 描述中带有’楚人美’这三个字的数据属于那个班级
- 模型类名_属性名_比较运算符,实际上就是处理的数据库中的join
Django中查询条件有失去问题
- 关闭django中自定义的时区
- 在数据库中创建对应的时区表
Django2.0后设置外键要加属性on_delete=models.CASCADE
- 如:user=models.OneToOneField(User,on_delete=models.CASCADE)
聚合函数
- 使用聚合函数
- Avg:平均值
- Count:数量
- Max:最大
- Min:最小
- Sum:求和
- Student.objects.aggregate(Max(‘sage’))
F对象
- 可以使用模型的A属性与B属性进行比较
- grades = Grade.objects.filter(ggirlnum__gt=F(‘gboynum’))
- F对象支持算术运算
- grades = Grade.objects.filter(ggirlnum__gt=F(‘gboynum’)+10)
Q对象
-
过滤器的方法中的关键参数,长用于组合条件
- 年龄小于25
- student.objects.filter(Q(sage__lt=25))
- 年龄小于25
-
Q对象语法支持 |(or),&(and),~(取反)
- 年龄大于等于的
- Student.objects.filter(~Q(sage__lt=25))
- 年龄大于等于的
模型成员
- 类属性
- 显性:自己写的那些
- 隐性:objects是一个Manager类型的一个对象,作用于数据库进行交互
- 当模型类没有指定管理器的时候,Django会自动为我们创建模型管理器
- 当然我们也可以自定义管理器,
class Student(models.Model): stuManager = models.Manager()
- 当自定义模型管理器时,objects就不存在了,Django就不会为我们自动生成模型管理器