共计 6296 个字符,预计需要花费 16 分钟才能阅读完成。
一、概述
-
主表
没有声明关系的表为主表
-
从表
声明关系的表为从表
-
对应关系
- 1:1 一对一
- 1:N 一对多
- M:N 多对多
-
一对一以及一对多共同属性 on_delete
-
作用
控制删除
-
值
-
models.CASCADE 默认值
当主表的数据删除 则从表数据 默认删除
-
models.PROTECT 保护模式
删除主表数据,如果从表中有关联的数据则无法实现删除 删除从表数据,主表数据不动
-
models.SET_NULL 空值模式
当主表数据被删除 则从表外的字段的值 设置为 null 一定将这个字段 设置为 null=True
-
models.SET_DEFAULT 默认值模式
-
-
二、一对一
-
说明
使用 OneToOneField 创建 1 对 1 的模型关系 将要创建对应关系的模型添加 OneToOneField
-
使用场景
表的字段太多,需要拆分
-
关系的位置
哪张表都可以
-
创建模型 User 和 IdCard
创建模型 User
# 创建用户表 class User(models.Model): username = models.CharField(max_length=20,db_index=True,null=True) sex = models.BooleanField(default=True) age = models.IntegerField(default=20) info = models.CharField(max_length=100,default='info') icon = models.CharField(max_length=60,default='default.jpg') isDelete = models.BooleanField(default=False) createTime = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'users'
创建模型 IdCard 并添加模型一对一关系 OneToOneField
#1 对 1 的表关系 class IdCard(models.Model): num = models.CharField(max_length=18) name = models.CharField(max_length=8) sex = models.BooleanField(default=True) birth = models.DateTimeField(auto_now_add=True) address = models.CharField(max_length=100,default='地址') # user = models.OneToOneField(User) #1 对 1 的外键 默认删除 # 保护模式 如果删除主表中与从表对应关系的数据 则不能删除 # user = models.OneToOneField(User,on_delete=models.PROTECT) # 保护模式 user = models.OneToOneField(User,on_delete=models.SET_NULL,null=True) class Meta: db_table = 'idcards'
-
一对一数据添加
说明:先添加主表数据 通过主表数据关联添加从表数据
添加主表 User 数据
# 添加用户信息 def adduser(req): u = User.addUser('lucky') u.save() return HttpResponse('添加用户信息')
添加从表 IdCard 数据
# 添加 1 对 1 的 idcard 数据 def addIdCard(req): import random u = User.objects.first() idcard = IdCard(num=random.randrange(1000000000,10000000000),name='lucky',user=u) idcard.save() return HttpResponse('添加卡的信息')
-
一对一数据查询–主获取从
说明:关系是隐性属性
格式:主表对象. 从表模型类名小写. 从表属性
需求:通过一用户,获取他的身份信息
# 数据查询 def showOneToOne(req): u = User.objects.first() print(u.idcard) #idcard 关联的数据 print(u.idcard.num) # 取出 idcard 对象的 num 属性 return HttpResponse('一对一数据的查询')
-
一对一数据查询–从获取主
说明:关系是直接声明的,它是一个显性的属性
格式:从表对象. 外键属性. 主表属性
需求:通过身份证信息查询用户的信息
# 数据查询 def showOneToOne(req): idcard = IdCard.objects.first() print(idcard.user) # 查询卡对应用户的对象 print(idcard.user.icon) # 查询卡对应用户的对象的 icon 属性 return HttpResponse('一对一数据的查询')
-
一对一数据的删除
说明:删除主表和从表查看关系变化以及更改 on_delete 属性
删除主表数据
# 数据的删除 def deleteOneToOne(req): # 删除主表数据 默认从表数据随着主表数据而删除 u = User.objects.first() u.delete() return HttpResponse('删除了第一个主表的数据')
删除从表数据
# 数据的删除 def deleteOneToOne(req): # 删除从表数据 主表数据 没有改变 idcard = IdCard.objects.first() idcard.delete() return HttpResponse('删除了第一条从表的数据')
三、一对多
-
说明
使用 ForeignKey 创建一对多的模型关系 将要创建对应关系的模型添加 ForeignKey
-
关系的位置
写在多的那一端
-
创建模型 grade 和 students
# 班级表 class Grade(models.Model): gname = models.CharField(max_length=15) gnum = models.IntegerField() ggirlnum = models.IntegerField() gboynum = models.IntegerField() class Meta: db_table = 'grades'
# 学生表 class Students(models.Model): sname = models.CharField(max_length=10) ssex = models.BooleanField(default=True) sage = models.IntegerField(default=20) sgrade = models.ForeignKey(Grade, on_delete=models.CASCADE) #1 对多的外键 默认删除 # sgrade = models.ForeignKey(Grade,on_delete=models.PROTECT) #保护模式 如果删除主表中与从表对应关系的数据 则不能删除 # sgrade = models.ForeignKey(Grade,on_delete=models.SET_NULL, null=True) # 保护模式 # sgrade = models.ForeignKey(Grade, on_delete=models.SET_DEFAULT, default=1) # 设置默认值 def __str__(self): return self.sname class Meta: db_table = 'students'
-
一对多数据添加
说明:先添加主表数据 通过主表数据关联添加从表数据
添加班级数据
# 添加 grade 信息 def addGrade(req): Grade(gname='python1807',gnum=63,ggirlnum=6,gboynum=57).save() Grade(gname='python1808',gnum=50,ggirlnum=2,gboynum=48).save() return HttpResponse('添加 grade 信息')
给班级添加对应学生数据
# 添加 students 信息 def addStudents(req): Students(sname='孙悟空',sgrade=Grade.objects.get(pk=1)).save() Students(sname='猪八戒',sgrade=Grade.objects.get(pk=1)).save() Students(sname='沙僧',sgrade=Grade.objects.get(pk=2)).save() Students(sname='唐僧',sgrade=Grade.objects.get(pk=2)).save() return HttpResponse('添加 students 信息')
-
一对多数据查询–主获取从
说明:关系是隐性属性
格式:主表对象. 从表模型类名小写_set. 过滤器
需求:已知一个班级,获取该班级中的所有学生
#1 对多查询 def oneToManyShow(req): g = Grade.objects.get(pk=1) s = g.students_set.all() for i in s: print(i) return HttpResponse('查询一对多')
-
一对多数据查询–从获取主
说明:关系是直接声明的,它是一个显性的属性
格式:从表对象. 外键属性. 主表属性
需求:已知一个学生,获取该学生所在班级的信息
# 一对多查询 def oneToManyShow(req): s = Students.objects.get(pk=1) s = s.grade.name return HttpResponse('查询一对多')
-
一对多数据删除
删除主表数据 (查看从表数据变化)
# 删除主表数据 默认还是 主表数据删除 从表对应数据也被删除 def deleteGrade(req): g = Grade.objects.first() name = g.gname g.delete() return HttpResponse('删除主表数据 {}'.format(name))
删除从表数据 (查看主表数据变化)
# 删除主表数据 默认还是 主表数据删除 从表对应数据也被删除 def deleteStudents(req): s = Students.objects.first() name = s.gname s.delete() return HttpResponse('删除从表数据 {}'.format(name))
四、多对多
-
说明
使用 ManyToManyField 创建多对多的模型关系 将要创建对应关系的模型添加 ManyToManyField
-
原理
底层是通过两个外键实现,单独有一张表来管理外键,自动生成
-
关系的位置
哪张表都可以
-
创建模型 User 和 Posts
# 创建用户表 class User(models.Model): username = models.CharField(max_length=20,db_index=True,null=True) sex = models.BooleanField(default=True) age = models.IntegerField(default=20) info = models.CharField(max_length=100,default='info') icon = models.CharField(max_length=60,default='default.jpg') isDelete = models.BooleanField(default=False) createTime = models.DateTimeField(auto_now_add=True) def __str__(self): return self.username class Meta: db_table = 'user'
# 以下为多对多 posts 关联用户 class Posts(models.Model): title = models.CharField(max_length=20,default='标题') article = models.CharField(max_length=200,default='article') createtime = models.DateTimeField(auto_now=True) users = models.ManyToManyField(User) def __str__(self): return self.title class Meta: db_table = 'posts'
-
多对多添加数据
User 与 Posts 模型数据正常添加
# 添加用户信息 def adduser(req): u = User.addUser('lucky') u.save() return HttpResponse('添加用户信息') # 添加 posts 信息 def addPosts(req): Posts(title='以后的你感谢现在拼搏的自己').save() Posts(title='阿甘正传').save() Posts(title='斗罗大陆').save() return HttpResponse('添加 Posts 信息')
添加一个多对多的数据 add
# 添加收藏 def addColl(req): u1 = User.objects.first() p1 = Posts.objects.first() p1.users.add(u1) return HttpResponse('添加多对多的数据')
添加多个多对多的数据 add
# 添加收藏 def addColl(req): u1 = User.objects.first() u2 = User.objects.last() p = Posts.objects.get(pk=2) p.users.add(u1,u2) # 添加多个对象 return HttpResponse('添加多对多的数据')
-
多对多数据查询–主获取从
说明:关系是隐性属性
格式:主表对象. 从表模型类名小写_set. 过滤器
需求:查询用户收藏哪些帖子
# 查询 用户收藏了哪些帖子 def showPosts(req): u = User.objects.first() data = u.posts_set.all() for i in data: print(i) return HttpResponse('查询收藏了哪些帖子')
-
多对多数据查询 从获取主
说明:关系是直接声明的,它是一个显性的属性
格式:从表对象. 外键属性. 过滤器
需求:已知一个博客 查询都被哪些用户收藏
# 查看帖子对应多的关系 def showUsers(req): p1 = Posts.objects.first() data = p1.users.all() for i in data: print(i) return HttpResponse('查询帖子被哪些用户收藏了')
-
多对多数据删除
删除一条数据
# 删除 def deleteData(req): p1 = Posts.objects.first() u1 = User.objects.first() p1.users.remove(u1) return HttpResponse('1 号用户取消收藏 1 号帖子')
删除多条数据
# 删除 def deleteData(req): p2 = Posts.objects.get(pk=1) u1 = User.objects.first() u2 = User.objects.get(pk=2) p2.users.remove(u1,u2) return HttpResponse('1、2 号用户取消收藏 1 号帖子')