数据库表和表都是有关联的,一般分为一对一、一对多和多对多。
一对一就是一张表的数据与另外一张表的数据是一一对应关系。
一对多是一张表的一条数据对应于另一张表的多条数据。如学校表和班级表,一个学校包含多个班级。
多对多是一张表的多个数据对应另一张表的多条数据。如班级表和学生表,一个班级有多个学生,一个学生属于多个班级。
在ORM中可以跨表执行增删改查,跟单表的增删改查稍有区别。
views.py示例(表结构查看python自动化运维学习第二十天–ORM增删改查)
def test(request):
#跨表查询(一对多)
_cla = "python1班"
obj = models.Classes.objects.filter(name=_cla)[0]
print(obj.name,obj.sch.name, obj.sch.mac)
#多对多跨表查询
for i in obj.user.all(): #根据获取的班级查询学生
print(i.name, i.username)
#跨表插入
sch_obj = models.School.objects.create(name="清华", mac="http://www.tsinghua.edu.cn", email="webmaster@tsinghua.edu.cn")
class_obj = models.Classes.objects.create(name="天体物理", sch=sch_obj) #根据学校对象sch_obj关联新建班级
print(class_obj.sch.name)
#跨表修改和删除班级
models.Classes.objects.filter(sch__name="new_east").update(name="python班") #在班级表中修改学校名称,学校名称中间是双下划线
models.Classes.objects.filter(sch__name="school11").delete() #跟修改一样需要双下划线连接class表中sch字段名和school表中name字段名
#多对多插入(user表中添加数据,关联到班级)
class_obj = models.Classes.objects.filter(name=_cla)[0]
user_obj = models.UserInfo.objects.create(name="吴迪", username="wu")
class_obj.user.add(user_obj.id) #在class和user的关系表中插入数据
# 多对多插入(user表中已有数据,关联到班级)
class_obj = models.Classes.objects.filter(name=_cla)[0] #查询
user_obj = models.UserInfo.objects.filter(name="李四") #查询
class_obj.user.add(*user_obj) #在class和user关系表中插入数据
# 多对多删除(实际操作只会删除class和user的关系表)
class_obj = models.Classes.objects.filter(name=_cla)[0]
user_obj = models.UserInfo.objects.filter(name="李四")
class_obj.user.remove(*user_obj) #删除关系表中指定单条数据
class_obj.user.clear() #删除关系表中所有相关class的数据
#多对多修改就是执行删除再执行插入
return HttpResponse("跨表操作")
多对多表关系中,从创建关系的表中对另一张表进行操作为正向,反之为反向。如classes表和userinfo表,这两张表的关系是在classes表中创建的,从classes表中查询userinfo表为正向查询,从userinfo表查询classes表为反向查询。
这种情况的增删改查操作如下:
#反向查询
user_obj = models.UserInfo.objects.filter(name="张三").first() #获取指定user对象
for item in user_obj.classes_set.all(): #取出该user所有classes
print(item.name)
#下面这种方法跟上面效果一样,其中classuser是在models中创建关系时定义的related_name,在增加和删除中都可以使用
for item in user_obj.classuser.all():
print(item.name)
#在models的Classes类中定义class和userinfo关系,添加related_name。这样第一种查询方法就不能使用了,会报错没有classes_set属性
# user = models.ManyToManyField(to="UserInfo", related_name="classuser")
#反向增加(class和user关系表)
user_obj = models.UserInfo.objects.filter(name="张三").first()
class_obj = models.Classes.objects.first(name="python班")
user_obj.classes_set.add(*class_obj)
#user_obj.classuser.add(*class_obj)
#反向删除(class和user关系表)
user_obj = models.UserInfo.objects.filter(name="张三").first()
class_obj = models.Classes.objects.first(name="python班")
user_obj.classes_set.remove(*class_obj) #删除指定关系
user_obj.classes_set.clear() #删除所有关系
#user_obj.classuser.remove(*class_obj) #删除指定关系
#user_obj.classuser.clear() #删除所有关系
#修改是先删除后插入