1、Django对各种数据库提供了很好的支持
Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库
2、配置数据库
1. 修改工程目录下的__init__.py文件
import pymysql
pymysql.install_as_MySQLdb()
3、开发流程
1.配置数据库
2.定义模型类--一个模型对应一张数据表
3.生成迁移文件
4.执行迁移生成数据表
5.使用模型类进行增删改查操作
4、ORM
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0KIOgy28-1631578012064)(C:\Users\My\AppData\Roaming\Typora\typora-user-images\image-20210815104825780.png)]
1.定义:对象-关系-映射
2.任务:
a、根据对象的类型生成表结构
b、将对象、列表的操作转换为sql语句
c、将sql语句查询到的结果转换为对象、列表
3.优点:极大减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码
5、定义模型
模型、属性、表、字段间的关系:一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段
定义属性:
概述
-django根据属性的类型确定以下信息
·当前选择的数据库支持字段的类型
·渲染管理表单时使用的默认html控件
·在管理站点最低限度的验证
-django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
-属性命名限制
·遵循标识符规则
·由于django的查询方式,不允许使用连续的下划线
库
-定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中
-使用方式
·导入from django.db import models
·通过models.Field创建字段类型的对象,赋值给属性
逻辑删除
-对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False
字段类型
-AutoField
·一个根据实际ID自动增长的IntegerField,通常不指定如果不指定,
·一个主键字段将自动添加到模型中
-CharField(max_length字符长度)
·字符串,默认的表单样式是TextInput
-TextField
·大文本字段,一殷超过4000使用,默认的表单控件是Textarea
-IntegerField
·整数
-DecimalField(max _digits None,decimal placesNone)
·使用python的Decimal实例表示的十进制浮点数
·参数说明
·DecimalField.max digits
·位数总数
·DecimalField.decimal_places
.小数点后的数字位数
-FloatField
·用Python的float实例来表示的浮点数
-BooleanField
·true/false字段,此字段的默认表单控制是CheckboxInput
-Nul1BooleanField
·支持null、true、false三种值
-DateField[auto _now=False,auto_now_add=False])
·使用Python的datetime.date实例表示的目期
.参数说明
-DateField.auto_now
·每次保存对象时,自动设置该字段为当前时间,用于
"最后一次修改"
的时间戳,它总是使用当前日期,默认为false
-DateField.auto_now_add
·当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
·说明
·该字段默认对应的表单控件是一个TextInput.在管理员站点添加了一个JavaScript写的日历控件,和一个"Today"的快捷按钮,包含了一个额外的invalid_date错误消息键
·注意
-auto_now_add,auto_now,and default这些设置是相i排斥的,他们之间的任何组合将会发生错误的结果
-TimeField
·使用Python的datetime.time实例表示的时间,参数同DateField
-DateTimeField
·使用Python的datetime.
datetime实例表示的日期和时间,参数同DateField
-FileField
.一个上传文件的字段
-ImageField
·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项
概述
-通过字段选项,可以实现对字段的约束
·在字段对象时通过关键字参数指定
-null
·如果为True,Django将空值以NULL存储到数据库中,默认值是False
-blanke
-如果为True,则该字段允许为空自,默认值是 False
-注意
-null是数据库范畴的概念,blank是表单验证证范畴的
-db_column
·字段的名称,如果未指定,则使用属性的名称
-db_index
·若值为True,则在表中会为此字段创建索引
-default
·默认值
-primary key
·若为True;则该字段会成为模型的主键字段
-unique
-如果为True,这个字段在表中必须有唯一值
关系
·分类
-ForeignKey一对多,将字段定义在多的端中
-ManyToManyField:多对多,将字段定义在两端中
-Oneto0neField:一对一,将字段定义在任意一端中
-用一访问多
-格式
·对象.模型类小写_set
·示例
grade.students_set !
·用一访问一
-格式
-对象.模型类小写
·示例
-grade.students
·访问id
-格式
-对象.属性_id
-示例
-student.sgrade_id
6、创建模型类
7、元选项Meta类
1. 在模型类中创建Meta类,用于设置元选项
2. db_table:定义数据库表名
3. ordering:['id'] ['-id']根据某字段排序,排序会增加资源使用率
8、模型成员
1、模型类的属性:
-
objects:默认管理器
1. 是Manager类型的一个对象,作用是与数据库交互
2. 当定义模型类没有指定管理器,则Django为模型创建一个名为objects的管理器 -
自定义管理器
class Students(models.Model): # 当为模型指定模型管理器,Django就不在为模型类生成objects模型管理器 # 自定义管理器 stuObj = models.Manager()
-
自定义管理器Manager类
- 模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器
- 作用:
- 向管理器类中添加额外的方法
- 修改管理器返回的原始查询集,重写get_queryset()方法
class StudentsManager(models.Manager):
def get_queryset(self):
# super()方法是调用父类的方法
return super(StudentsManager,self).get_queryset().filter(idDelete=False)
class Students(models.Model):
#自定义模型管理
#当自定义模型管理器,objects就不存在了
stuObj = models.Manager()
stuObj2 = StudentsManager()
2、创建对象
-
创建对象目的:向数据库中添加数据
-
当创建对象时,django不会对数据库进行读写操作,当调用save()方式时才与数据库交互,讲对象保存到数据库表中
-
创建对象注意:
__init__方法已经在父类models.Model中使用,在自定义的模型中无法使用
-
创建对象方法(两种方法)
-
在模型类中增加一个类方法# 需要在函数上加装饰器@classmethod,注明是类方法
class Students(models.Model): @classmethod def createStudent(cls,name,age,gender,contend,grade,lastTime,createTime, isDelete=False): # cls就相当于是Students类 stu = cls(sname = name,sage = age,sgender = gender, scontend = contend,sgrade = grade,supdateTime = lastTime, screateTime = createTime,isDelete = isDelete) return stu
-
在自定义管理器中添加方法
class StuManager(models.Manager):# 自定义Students管理器 def createStudent(self,name,age,gender,contend,grade,updateTime, createTime,isDelete=False): stu = self.model() # 实例对象,Students对象 stu.sname=name stu.sage = age stu.sgender = gender stu.scontend = contend stu.sgrade = grade stu.supdateTime = updateTime stu.screateTime = createTime stu.isDelete =isDelete return stu
-
9、模型查询
1、概述
- 查询集表示从数据库获取的对象集合
- 查询集可以有多个过滤器
- 过滤器就是一个函数
- 从sql的角度来说,查询集合select语句等价,过滤器就等价于where条件
2、查询集
1、在管理器上调用过滤方法,返回查询集
2、查询集经过过滤器筛选后,返回新的查询集,所以可以写成链式调用
3、惰性执行
-
创建查询集不会带来任何数据的访问,直到调用的时候,才会访问数据
# 这里只是创建了查询集,不会访问数据库 books = BookInfo.objects.all() # 遍历books的时候才会访问数据库查询 for book in books: print(book.name)
4、如下情况才会直接访问数据库
- 迭代
- 序列号
- 与if合用
5、返回查询集的方法成为过滤器(返回多条数据)
-
all()
-
返回查询集中的所有数据,返回的是一个对象
Grades.objects.all()
-
-
filter()
-
保留符合条件的数据
-
filter(键=值)
-
filter(键=值,键=值)----或
-
filter(键=值).filter(键=值)-----且
Grades.objects.filter(gname='class01')
-
-
exclude() # 过滤掉符合条件的数据
Grades.objects.exclude(gname='class01')
-
order_by() # 排序
Grades.objects.order_by('pk')
-
values()
- 一条数据就是一个对象(字典),返回一个列表
- 用法与all()差不多,返回的是具体的值,all()是一个对象,看不到具体的值
6、返回单个数据
- get():只能返回一个值,为空或者返回多个都会报错
- 返回一个满足条件的对象(返回对象中定义__str__方法的内容)
- 注意:
- 如果没有找到符合条件的对象,模型类会引发异常(DoesNotExist)
- 如果找到多个对象,模型类也会引发异常(MultipleObjectsReturned)
- count()
- 返回当前查询集对象的个数
- first()
- 返回查询集中的第一个对象
- last()
- 返回查询集中的最后一个对象
- exists()
- 判断查询集中是否有数据,有数据返回True
7、限制查询集
-
查询集返回列表,可以用下标的方法进行限制,等同于sql中的limit语句
-
下标不能是负数
def stufenye1(request, page): # 分页显示学生 print(stufenye1) page = int(page) stu = Students.stuObj.all()[(page - 1) * 5:page * 5] return render(request, 'myApp/students.html', {'students': stu})
8、查询集的缓存(需要看看开发文档)
- 概述:
- 每个查询集都包含一个缓存,来最小化的对数据库访问
- 在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生缓存,django会将查询出来的数据做一个缓存,并返回查询结果,以后的查询直接使用查询集的缓存
- 参考:https://blog.youkuaiyun.com/weixin_43835542/article/details/108379434
9、字段查询
- 概述
- 实现了sql中的where语句,方法filter(),exclude(),get()的参数
- 语法:属性名称_比较运算符=值
- 外键:属性名_id
- 转义:
- 类似SQL中的like语句
- 比较运算符
-
exact
- 全匹配,判断,大小写铭感
- 例如:filter(isDelete=True) filter(isDelete__exact=True)
-
contains:是否包含,大小写敏感 filter(sname__contains=‘王’)
-
startswith、endswith:以value开头或者结尾的,如:
filter(sname__startswith='刘') filter(sname__endswith='凡')
-
以上四个在前面加上i,就表示不区分大小写:iexact、icontains、istartswith、iendswith
-
isnull、isnotnull:是否为空,如filter(sname__isnull=False)
只有数据库保存null时,判断结果才为True
-
in:包含在list里面,如filter(sname__in=[‘王伟’,‘王一凡’])
-
gt/gte/lt/lte:大于/大于等于/小于/小于等于,如filter(pk__gt=10)
-
year/month/day/week_day/hour/minute/second:时间,如filter(createtime__year=2017)
-
跨关联查询–处理join查询–语法:
-
查询快捷:pk代表主键
-
- 聚合函数,需要引入包from django.db.models import Avg,Count,Max,Min,Sum
-
使用aggregate()函数返回的值,如
Grades.objects.aggregate(Avg(ggrilnum))
-
Avg
-
Count
-
Max
-
Min
-
Sum
-
- F对象,需要引入包from django.db.models import F
- 可以使用模型的A属性和B属性做比较,如查询女生数量大于男生数量的数据filter(ggirlnum__gt=F(‘gboynum’))
- 支持F对象的算数运算,如如查询女生数量大于(男生数量加2)的数据filter(ggirlnum__gt=F(‘gboynum’)+2)
- 可以做一个时间的加减
- Q对象,需要引入包from django.db.models import Q
-
概述:过滤器的方法中的关键字参数,条件为And模式
-
需求:进行or查询
-
解决:使用Q对象
def qqq(request): # stu = student.stuobj.get(Q(sname__startswith='t') & Q(sage=18)) # and # stu = student.stuobj.get(Q(sname__startswith='t') , Q(sage=18)) # and stu = student.stuobj.filter(Q(sname__startswith='t') | ~Q(sage=18) ) # or 非 return render(request,'index.html',{'stu':stu})
-
10、模型字段索引
-
概述:索引就像是文档目录,方便快速查找到相应数据,但是添加索引会占用资源,增加服务器压力
-
字段选项添加
title = models.CharField('标题', max_length=200, db_index=True)
-
Meta元数据中添加
class Meta: indexes = [models.Index(fields=['title']),]
11、修改和删除数据
-
查询出数据直接修改(update())、删除(delete())
Students.stuObj1.get(pk = num).delete()
-
查询出数据,然后实例化,修改、删除
stu = Students.stuObj1.get(pk = num).delete() stu.delete()
-
注意:update的时候,不能用get筛选数据,可以用filter