关联表的数据操作
1. 单表数据操作
objects:管理器
2.one-to-many(正向/反向增删改查)
2.1. 正向
一个模型如果有一个关联字段(外键字段),通过这个模型对外键关联的模型进行操作叫做正向。
1. # 增、改:无则增,有则改
a. 通过属性赋值的方式
s1 = Student(name='小辉', age=18, sex=0)
s1.grade = g1
s1.save()
b. 通过主键的方式
s2 = Student(name='liy', age=19)
s2.grade_id = g2.id
s2.save()
3. 通过获取进行更改
s3 = Student.objects.get(name='liy', age=19)
s3.grade = g1 #实现人员的grade更改
s3.save()
2. # 删
s2.grade = None
s2.save()
3. # 查
s1.grade
s1.grade.name
2.2. 反向
一个模型如果被另一个模型关联,通过这个模型对关联它的模型进行操作就叫做反向
实际:如果一个模型()Student)有关联字段(eg:ForeignKey),那么这个外键模型的实例(eg:g1)将可以访问一个管理器(eg:管理Student所有实例的管理器)。默认情况下,这个管理器名为有关联字段的模型小写名_set(eg:student_set)
1. # 增
a. 通过grade表创建student表数据
new_student = g2.student_set.create(name='浩浩', age=16)
b. 增加多条数据
s3,s4,s5,s6 = Student_set.objects.filter(id__lte=8) #在数据表中,s3,s4,s5,s6的id小于8
g1.student_set.add(s3,s4,s5,s6) #将s3,s4,s5,s6的grade_id添加为g1,即将s3,s4,s5,s6添加到班级1中去
2. # 删
a. 从相关对象中移除制定的模型对象
g1.student_set.remove(s1)
g1.student_set.remove(s2,s4)
b. 从相关对象中删除所有的对象
g1.student_set.clear()
3. # 改,有则改,无则增
g1.student_set.set([s1, s2, s3, s4, s5])
s6, s7 = Student_set.objects.filter(grade_id = 2)
g1.student_set.set([s6, s7])
4. # 查
a. 查询所有
g1.student_set.all()
b. 条件查询
g1.student_set.filter(age=16)
# 自定义反向关系管理器student_set-------->student # 即在将studet_set修改为student时,需要在Student类中grade的关系定义进行添加related_name='student'
grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='student')
g1 = Grade.objects.get(pk=1)
g1.student
总结:正向--模型通过关联字段的属性名操作关联模型
方向--被关联模型使用关联模型的小写模型名_set去操作
3.many-to-many(正向/反向增删改查)
赋值
s1 = Student.objects.get(pk=2)
c1 = Course.objects.get(pk=1)
e = Enroll()
e.student = s1
e.Course = c1 # Course在定义时首字母被大写
e.save()
3.1. 正向
c1.student.all() #关联字段属性名
增删改查同one-to-many
3.2. 反向
s1.course_set.all() # 使用的是源模型的小写模型名_set
注:同样可以在Course类中students的关系定义进行添加related_name='student',从而减去反向操作时,_set需求
4.one-to-one(正向/反向增删改查)
4.1. 正向
d1 = StudentDetail(address='长沙')
d1.student = s1
d1.save()
d1.student
增删改查同one-to-many
4.2. 反向 管理器对象不是一个对象的集合,而是一个单一的对象,名字叫源模型的小写模型名
d2 = StudentDetail(address='武汉')
s2 = Student.objects.get(pk=3)
s2.studengdetail =d2
s2.save()
d2.save()
s2.studentdetail
跨表查询
跨模型的相关字段的字段名,以双下划线隔开,知道你想要达到的字段为止。
1. 多对多
Course.objects.filter(student__sex=0) # 女生报名的课程
Student.objdects.filter(course__name__contains='python') # 选择python课程的学生姓名
2. 一对多
Student.objects.filter(grade__name = 'django框架‘) # django框架包含的所有学生
3. 一对一
StudentDetail.objects.values('address', 'student__name', 'student__age') # 学生详情表中地址、学生姓名、学生年龄信息
Student.objects.values('name', 'age', 'studentdetail__address') # 学生表中学生姓名、年龄、以及地址信息
复习总结
一. 关联表的数据操作
1. OneToMany:
class Student(models.Model):
......
grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True, related_name='student')
2. ManyToMany:
class Course(models.Model):
......
students = models.ManyToManyField('Student', through='Enroll', related_name='course')
正向:
模型里有关联字段,这个模型我们称为源模型,通过这个模型对关联的模型进行操作(字段本身的属性名)
s1.grade.name 通过学生的班级属性拿到学生的班级名称
c1.student.all() 通过课程拿到报名该课程的所有学生
反向:管理器对象不是一个对象的集合,而是一个单一的对象,名字叫源模型的小写模型名
g1.student_set.all() 通过班级信息去拿到该班级下所有的学生信息,此处student_set因related_name='student',直接为student
s1.course_set.all() 通过学生信息反向去拿学生报名的课程信息,此处course_set因related_name='course',直接为course
3. OneToOne:
class StudentDetail(models.Model):
......
student = models.oneToOneFiled('student', on_delete=models.CASCADE)
正向:d1.student.name 通过学生详情实例正向拿到学生姓名 d1为源模型实例
反向:s1.studentdetail.age 通过学生信息反向去拿到学生的年龄
二. 跨表查询
__跟踪关系,正向使用字段名,反向模型小写名
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)