开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第37天,点击查看活动详情
模型基础三表关联对象及多表查询
一,关联表数据操作
1.1,复习数据操作(增删改查)
1.g1 = Grade.objects.create(name='Django框架', num=41)
2.g2 = Grade.get_or_create(name='爬虫框架', num=39)
3.g3 = Grade(),g3.name='Web前端',g3.num='41',g3.save()
3.g4 = Grade(name='Tornado框架', num=30),g4.save()
1.2,OneToMany(增删改查)
'''
正向:如果一个模型有外键字段,通过这个模型对外键进行操作,比如imformation模型有一个外键字段grade,imformation对grade进行操作
反向:一个模型如果被另外一个模型外键关联,通过这个模型对关联他的模型进行操作。比如grade被imformation模型里的grade进行外键关联,grade对student操作
'''
1),正向增删改查
1.增,改
# 通过属性赋值的方式
g1 = Grade.objects.get(pk=1)
s1 = Imformation.objects.get(pk=1)
s1.grade = g1
s1.save()
# 通过主键的方式
g2 = Grade.objects.get(pk=2)
s2 = Imformation.objects.get(pk=2)
s2.grade_id = g2.id
s2.save()
2.查
In [18]: s1.grade # 通过s1这个学生grade这个属性
Out[18]: <Grade: Django框架班-41期>
In [19]: s1.grade_id # 直接操作s1的数据库字段
Out[19]: 1
In [20]: s1.grade.name # 通过grade联系到Grade表
Out[20]: 'Django框架'
3.删(赋值None)
In [27]: s1.grade=None
In [28]: s1.save()
2),反向增删改查
'''
管理器:g1.imformation__set.all()
实际访问情况:如果一个模型有外键(eg:Imformation模型),那么这个模型的实例(eg:grade模型的实例g1)将可以通过一个管理器(返回的是Imformation模型所有实例的管理器),默认情况下,管理器的名为(imformation_set),imformation是Imformation的小写
'''
1.增
g1 = Grade.object.get(pk=2)
ns = g1.imformation_set.create(name='F', age=28)
ns:<Imformation: (姓名:F-年龄:28-班级:2)>
# 通过Grade这个模型往Imformation这个模型里面添加
2.批量增加
s1, s2, s3 = Imformation.objects.filter(pk__lte=3)
g1.imformation_set.add(s1, s2, s3)
3.删
g1.imformation_set.clear()
g1.imformation_set.remove(s1)
4.改
g1.imformation_set.set([s1, s2, s3])
# 在列表里面的修改班级为当前g1,不在这个里面的即使是属于g1这个班也变成null
5.查
g1.imformation_set.all()
g1.imformation_set.get(pk=1)
3),修改管理器名
grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='imformation')
# 把imformation_set这个管理器命名成imformation
g1 = Grade.objects.get(pk=4)
In [2]: g1 = Grade.objects.get(pk=4)
In [3]: g1.imformation.all()
Out[3]: <QuerySet [<Imformation: (姓名:A-年龄:19-班级:4)>, <Imformation: (姓名:B-年龄:21-班级:4)>, <Imform-年龄:25-班级:4)>]>
1.3,ManyToMany(增删改查)
'''
正向
eg:course里面有ManyToMany字段,模型使用该字段本身的属性名student
'''
1.增,通过中间表
s1 = Imformation.objects.get(pk=1)
c1 = Course.objects.get(name='python')
e = Enroll()
e.studnet = s1
e.course = c1
e.save()
2.查
c1 = Course.objects.get(pk=1)
c1.student.all()
'''
反向
(原始模型的小写模型名,加上set --> course_et)
'''
1.查
s1 = Imformation.objects.get(pk=1)
s1.course_set.all()
1.4,OneToOne
正向
1.增
In [12]: d1 = Detail(college='北京五道口某高校')
In [13]: s1
Out[13]: <Imformation: (姓名:A-年龄:19-班级:4)>
In [14]: d1.student = s1
In [15]: d1.save()
2.查询
d1 = Detail.objects.get(pk=1)
d1.student.id
d1.student.name
反向
原始模型的小写模型名
s1.detail.college # 不需要写成s1.detail_set.college
二,跨表查询
Detail.objects.values('college', 'student__name', 'student__id')
Imformation.objects.values('name', 'sex', 'detail__college')
Imformation.objects.filter(detail__college='北京五道口某高校') # 查询学校是北京五道口...的学生
Course.objects.filter(student__sex=1) # 男生报名的课程
Imformation.objects.filter(course_name='python') # 报了’python‘课程的人
Imformation.objects.filter(course__name='python', grade__num=8) # 报名了python,班期为8的学生
Imformation.objects.filter(detail__college='北京五道口某高校', course__name='python') # 查询学校是'北京...'报名课程为python的学生
Imformation.objects.filter(enroll__pay__lt=100) # 查看缴费小于1000的学生
Grade.objects.filter(imformation__course__name='python') # 报名了python课程的班级有哪些,distinct()去重