阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

数据库模型关系

190次阅读
没有评论

共计 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 号帖子')

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-05-26发表,共计6296字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中