Django ORM学习

    xiaoxiao2022-07-14  169

    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 shellfrom 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改为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

    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))| 和 ~用法相同
    最新回复(0)