lxinghua

博客园 首页 新随笔 联系 订阅 管理

关联表的数据操作

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   通过学生信息反向去拿到学生的年龄

二. 跨表查询

  __跟踪关系,正向使用字段名,反向模型小写名

posted on 2022-11-07 20:27  興華  阅读(447)  评论(0编辑  收藏  举报