Django ORM
重点:对对象操作,结果体现在数据库上。
不修改表的结构的话,不需要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 shell
- from courses.models import Teacher #要插入的表所对应的类
- t = Teacher(nickname=‘Jack’) #创建对象
- t.save() #保存到数据库
- exit
- python脚本
- 数据库
- fixture序列化
- 命令行
-
Django导出数据(略)
Models API
-
查询 返回新的QuerySet
-
相关API
-
QuerySet 查询集
-
fans nickname均为Teacher类的属性
-
- Teacher.objects.all() # 返回所有结果
-
- Teacher.objects.filter(fans__gte=500) # QuerySet可以是多条结果,返回粉丝数大于等于500
-
Teacher.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改为name
- Student.objects.all().only(‘nickname’,‘age’) # 只查询nickname,age属性
-
获取字典或元组类型的QuerySet
- Student.objects.values(‘nickname’,‘age’) # 返回值为字典列表,key为nickname,age
- Student.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())
- 一对多(外键) select_related()
-
反向查询
- 通过老师(父表)查询课程(子表),查询老师所教的课程
- Teacher.objects.get(nickname=‘Jack’).course_set.all() #course_set代表course表
-
聚合
- .annotate
- Course.objects.values(‘teacher’).annotate(vol=Sum(‘volume’)) # 返回字典列表,每个字典有教师姓名(因为在Course类中存储的teacher就是姓名)和课程volume属性的求和
- Avg求平均值
-
row()执行sql原生语句
-
-
不返回QuerySet的API
- 获取对象 仅一条数据(in_bulk除外)
- get() 指定id
- get_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() 创建或更新
- update() 更新
- 删除对象
- delete() 使用filter过滤
- Course.objects.filter(title=‘test’).delete()
- 其它操作
- exists() 查询是否存在,返回bool
- count() 返回记录数
- aggregate() 聚合,返回得到的值而不是记录
- Course.objects.aggregate(Max(‘price’),Avg(‘price’),Sum(‘volume’))
- 获取对象 仅一条数据(in_bulk除外)
-
自定义聚合查询
实现group_concat
F对象和Q对象
- F对象:操纵数据
- Course.objects.update(price=F(‘price’)-11) # 对所有课程价格-11
- 对两个字段进行比较
- Course.objects.filter(volume_lte=F(‘price’)*10) # 销量小于价格*10
- Q对象:操纵关系 & | ~
- 同时满足title包含java且销量大于5000 #双下划线
- Course.objects.filter(Q(title_ _icontains=‘java’)&Q(volume__gte=5000))
- | 和 ~用法相同
- 同时满足title包含java且销量大于5000 #双下划线