(九)Django学习——一对一,一对多,多对多关系表的各种数据操作;跨关联关系的多表查询!
1.关系表的数据操作
(1)一对多的数据插入:
①学院表信息的插入(使用了另一种方便的方法进行数据的插入)
②学生表信息的插入(使用常规视图插入数据)
from .models import User,Article,Department,Student,Course,Stu_detail
def add_user(request):
#1.根据模型类层面的属性进行数据的添加 属性赋值的方法
#因为我们在模型类有定义了一个department的属性, 而这个属性的对象的类型必须是department表的类实例对象
d = Department.objects.get(d_id=1) #学院表中北大的实例
Student.objects.create(s_name="小明",department=d) #外键department的字段值必须是实例
#2.根据数据库层面的字段名进行数据的添加 需要注意的是外键的值必须是关联表中已经存在的值.
Student.objects.create(s_name="小红", department_id=2)
return HttpResponse("插入数据成功!")
③观察可知插入成功:
(2)表关联对象的访问:
first:基操!
second:
**正向查询:Student的模型类中我们有定义department的属性,所以当我们去访问的时候,可以直接通过student.department的形式去找到某个学生的所属学院是哪个。
由此发出灵魂拷问:
如果我们也希望在在访问某个学院的实例对象的学生的时候该怎么访问呢???
**
third:
**反向查询:如果模型Student有一个ForeignKey(会自动给Department类添加一个反向查询的属性!),那么该ForeignKey 所指的模型Department实例可以通过一个管理器回到前面有ForeignKey的模型Studnet的所有实例。默认情况下,这个管理器的名字为student_set(可以在对应的表关联API中通过设置related_name的值来自定义),其中student是源模型的小写名称。
拓展:两个表关联的API(OneToOne,Foreignkey,ManyToMany)在谁那,通过谁去查询另一个表的信息就是正向查询;反之就是反向查询。
注意:只限一对多以及多对多;一对一没有_set属性,无法使用!!!
**
拓展:
**可以在定义时设置related_name 参数来覆盖student_set的名称.
**
fourth:
反向查询的一些实用方法:
注意:只限一对多以及多对多;一对一没有这些方法,无法使用!!!
from .models import User,Article,Department,Student,Course,Stu_detail
def add_user(request):
d = Department.objects.get(d_id=1) #学院表中北大的实例
d3 = Department.objects.get(d_id=3) #学院表中中科的实例
# create()方法:新建数据
d.student_set.create(s_name="小王") #在北大院系下新建一个学生表信息
# aa()方法:修改已经存在的数据(注意:通过实例)
s3 = Student.objects.get(s_id=3) #将s_id为3的学生的院系从北大换到中科
d3.student_set.add(s3)
return HttpResponse("插入数据成功!")
seventh:一对一表信息的访问
注意:一对一表关系中使用不了反向查询!!!
from .models import Department,Student,Course,Stu_detail
def add_user(request):
s1 = Student.objects.get(s_id=1) #获得一个学生的实例对象
print(s1.stu_detail)
print(dir(s1.stu_detail)) #会发现没有反向查询_set的属性!
print(s1.stu_detail.age) #只能进行数据查询,不能添加!
#注意:一对一关系的话,反向查询不能使用。所以添加数据只能如下:
Stu_detail.objects.create(Student_id=s1,age=18,phone=123456)
return HttpResponse("插入数据成功!")
eigth:多对多表关系:
第一部分:数据的添加及关联!
from .models import User,Article,Department,Student,Course,Stu_detail
def add_user(request):
s1 = Student.objects.get(s_id=1) #小明
c1 = Course.objects.get(c_id=1) #c
#1.数据库中已存在的数据 将学生表和课程表通过Django自动生成的中间表联系起来
s1.course.add(c1)
#2.数据库中没有的数据 将学生小明与新建的课程"人工智能"联系起来
s1.course.create(c_name="人工智能")
return HttpResponse("插入数据成功!")
没有执行之前Django自动生成的中间表是空的:
执行之后Django自动生成的中间表:
第二部分:数据的指定删除及全部删除!
from .models import Department,Student,Course,Stu_detail
def add_user(request):
s1 = Student.objects.get(s_id=1) #小明
c1 = Course.objects.get(c_id=1) #c
s1.course.remove(c1) #删除小明同学的课程c
s1.course.clear() #删除小明同学的所有课程
return HttpResponse("插入数据成功!")
2.多表查询—跨关联关系的查询
**Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段:
**
(得到的都是QuertSet型数据!)
from .models import Department,Student,Course,Stu_detail
def add_user(request):
#查询学院名为‘北大’的学生的信息
s_all = Student.objects.filter(department__d_name='北大')
print(s_all)
# 它还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称!!!
#查询学生名字中包含'小'的学生的学院信息
d_all = Department.objects.filter(student__s_name__contains='小')
print(d_all)
#查询学号为1的学生的所有的课程
c_all = Course.objects.filter(student__s_id=1)
print(c_all)
#查询报了课程3的所有学生
stu_all = Student.objects.filter(course__c_id=3)
print(stu_all)
#查询报了'python'课程的学生的所属学院的信息
cou_all = Department.objects.filter(student__course__c_name='python')
print(cou_all)
return HttpResponse("插入数据成功!")
上一篇: MyBatis一对多关联查询(级联查询)
下一篇: 多对多关系的多表关联查询