组团学

数据库模型关系

阅读 (264608)

一、概述

  • 主表

    没有声明关系的表为主表

  • 从表

    声明关系的表为从表

  • 对应关系

    • 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号帖子')
需要 登录 才可以提问哦