重点:对对象操作,结果体现在数据库上。
不修改表的结构的话,不需要make migrations 和make migrate
models.py 编写模型类
数据库和类之间的桥梁
类–表 对象–记录 属性–字段
模型类名==表名 继承models.Model
模型类字段 :mysql每种类型与models模块一一对应,例如 varchar 对应models.CharField()
关系型字段
一对一 助教和教师一对一在助教表中,添加字段teacher = models.OneToOneField(Teacher,on_delete = models.SET_NULL,null=True,blank=True)教师删除时,字段置空 一对多 对应外键 教师和课程一对多课程表中,添加字段 teacher = modules.ForeignKey(Teacher,on_delete=models.CASCADE)Teacher是teacher类名,添加删除级联 多对多 学生和课程多对多关系学生表中,添加字段 course = models.ManyToManyField(Course)Django会生成关联表courses_student_course字段参数 name = models.CharField(db_column = “age” ) 改变字段名为age,其他属性类似。如果在teacher app下的的user类,表名就是teacher_user
可以自关联,第一个参数写self或者类名。比如地址表可以有 省 城市 区记录,城市关联到省,区关联到城市。
元数据Meta
在类表中 class Meta: db_table = “address” #表名
ordering = ‘pid’ #排序
unique_together = (‘address’,‘note’) #两个字段不能同时相同
在子表中定义外键
Django中更改数据表
make migrations 创建数据库执行的sql语句,在migrations 文件夹下make migrate 执行migrations 中的文件,创建表Django导入数据到数据库
命令行 python3 manage.py shellfrom courses.models import Teacher #要插入的表所对应的类t = Teacher(nickname=‘Jack’) #创建对象t.save() #保存到数据库exit python脚本数据库fixture序列化Django导出数据(略)
查询 返回新的QuerySet
相关API
QuerySet 查询集
fans nickname均为Teacher类的属性
Teacher.objects.all() # 返回所有结果 Teacher.objects.filter(fans__gte=500) # QuerySet可以是多条结果,返回粉丝数大于等于500Teacher.objects.filter(fans_in=[666,1231]) # in操作
Teacher.objects.get(nickname = ‘Jack’) # get()只能返回一条结果使用切片 Teacher.objects.all() [:1]
排序 Teachers.objects.all().order_by(‘fans’) #升序排列 '-fans’降序排列链式查询 Teacher.objects.filter(fans__gte=500).order_by(‘fans’) #先查询fans大于500,再升序排列
查看原生sql语句 : str(Teacher.objects.all().query)
Teacher.objects.all().exclude(nickname = ‘Peter’) 在结果集中去除
Teacher.objects.all().reverse() 结果集反向排序 需要在Meta元数据中添加ordering distinct()实现字段别名,排除字段,选择字段
别名 Student.objects.all().extra(select={‘name’:‘nickname’}) # 将对象属性名由nickname改为nameStudent.objects.all().only(‘nickname’,‘age’) # 只查询nickname,age属性获取字典或元组类型的QuerySet
Student.objects.values(‘nickname’,‘age’) # 返回值为字典列表,key为nickname,ageStudent.objects.values_list(‘nickname’,‘age’) #返回值是元组列表,每个元组是(nickname,age)对 Student.objects.values_list(‘nickname’,flat = True) #返回值是列表根据日期时间查询
dates()datetimes()集合运算
并 p1 = Course.objects.filter(price__gte=240)p2 = Course.objects.filter(price__lte=260)p1.union(p2) 交 intersection() 补 difference()查询优化
一对多(外键) select_related() Course.objects.all().select_related(‘teacher’) #teacher是外键 多对多 prefetch_related() 根据学生查找所选课程students = Student.objects.filter(age__lt=30).prefetch_related(‘course’)for s in students: print(s.course.all())反向查询
通过老师(父表)查询课程(子表),查询老师所教的课程Teacher.objects.get(nickname=‘Jack’).course_set.all() #course_set代表course表聚合
.annotateCourse.objects.values(‘teacher’).annotate(vol=Sum(‘volume’)) # 返回字典列表,每个字典有教师姓名(因为在Course类中存储的teacher就是姓名)和课程volume属性的求和Avg求平均值row()执行sql原生语句
不返回QuerySet的API
获取对象 仅一条数据(in_bulk除外) get() 指定idget_or_create() 获取或创建first() 第一条last() 最后一条earliest() 最早创建latest() 最晚创建in_bulk() 批量返回对象,列表传入主键值 Courses.objects.in_bulk([‘course1’,‘course2’]) 创建对象 create() 单个创建bulk_create() 批量创建update_or_create() 创建或更新 更新对象 update() 更新 Course.objects.filter(title=‘Java教程’).update(price=300) update_or_create() 创建或更新 删除对象 delete() 使用filter过滤Course.objects.filter(title=‘test’).delete() 其它操作 exists() 查询是否存在,返回boolcount() 返回记录数aggregate() 聚合,返回得到的值而不是记录 Course.objects.aggregate(Max(‘price’),Avg(‘price’),Sum(‘volume’))自定义聚合查询
实现group_concat
