第七单元 ORM表关系及操作

7.1 多对一关系

7.1.1 多对一关系是什么

Django使用django.db.models.ForeignKey定义多对一关系。

ForeignKey需要一个位置参数:与该模型关联的类

class Info(models.Model):
      user = models.ForeignKey(other_model,on_delete=models.SET_NULL)

生活中的多对一关系:班主任,班级关系。一个班主任可以带很多班级,但是每个班级只能有一个班主任

from django.db import models
# id  name  gender  定义老师的模型类
class Teacher(models.Model):
    name = models.CharField(max_length=30,verbose_name="老师姓名")
    gender = models.CharField(max_length=10,verbose_name="老师性别")
    class Meta:
        db_table = "teachers"
    def __str__(self):
        return self.name
# id name gender score teacher_id
class Student(models.Model):
    name = models.CharField(max_length=20,verbose_name="学生姓名")
    gender = models.CharField(max_length=10,verbose_name="学生性别")
    score = models.IntegerField(verbose_name="学生分数")
    # to:后边写所关联的模型类  
    # on_delete=models.CASCADE:主表中数据删除,从表也删除
    # 外键关联的是整个模型类,不是单独的某一个对象
    # 但是通过模型类会产生一个相关联的字段  字段名_id
    teacher = models.ForeignKey(to=Teacher,on_delete=models.CASCADE,verbose_name="所属老师")
    class Meta:
        db_table = "students"
    def __str__(self):
        return self.name
7.1.2 多对一关系的增删改操作
添加老师语法:
	模型类.objects.create()
    Teacher.objects.create(name="王老师",gender="女")
删除老师语法:
	模型类.objects.get(条件).delete()
	# 删除id为2的老师
	Teacher.objects.get(id=2).delete()  # (3, {'myapp.Student': 2, 'myapp.Teacher': 1})									# 3代表一共删除的数据个数  Student删除3条 Teacher删除1
修改老师语法:
    模型类.objects.filter(条件).update()
	# 修改id为3的老师性别为女
	Teacher.objects.filter(id=3).update(gender="女")

以上创建了两条老师数据
由于我们设置外键关联可以为空null=True,所以此时在班级表创建时,可以直接保存,不需要提供老师数据

添加学生语法:
    模型类.objects.create()
	通过外键_id的形式来添加
 		Student.objects.create(name="李四",gender="男",score=80,teacher_id=3)
	直接给外键赋值一个老师对象
		t1 = Teacher.objects.create(name="李老师",gender="男")
		Student.objects.create(name="李四",gender="男",score=80,teacher=t1)
删除学生语法:
	模型类.objects.get(条件).delete()
    Student.objects.get(id=1).delete()
修改学生语法:
    模型类.objects.filter(条件).update(字段1,字段2...)
    Student.objects.get(id=1).update(name="张三")
  • 注意:要记得删除之后要重新获取一次数据,否则查看到的结果中还是之前获取到的有老师的班级数据
7.1.3 多对一的正向查询

将老师分配个班级之后,由于班级表关联了老师字段,我们可以通过班级找到对应老师
虽然老师表中没有关联班级字段,但是也可以通过老师找到他所带的班级,这种查询方式也叫作关联查询

# 查询id为2的学生的老师姓名
	--找到id2的学生
    stu = Student.objects.get(id=2)
    --找到stu对应的老师    stu.teacher.name
    stu.外键.name
7.1.4 多对一的反向查询

通过模型类名称后追加一个_set,来实现反向查询

反向查询:通过django的内置属性来进行查询  模型类(模型类小写)_set()可以反向查询老师名下的所有学生,
    # 查询id为1的老师的所有学生    --先找到id为1的老师    
    tea = Teacher.objects.get(id=1)    
    --查询tea老师名下的所有学生  老师对象.模型类_set.all()    
    tea.student_set.all()

7.2 一对一关系

7.2.1 一对一关系是什么

模型类使用OneToOneField用来定义一对一关系;

比如当你拥有一个老师表时,紧接着你还需要一个教授表,那么教授表可能拥有老师表的一系列属性,那么你还不想把老师表中的字段直接复制到教授表那么可以通过OnToOneField来实现教授表继承老师表。

OneToOneField(to, on_delete, parent_link=False, options)
class Teacher(models.Model):
    name = models.CharField(max_length=50)
    age = models.CharField(max_length=50)
    def __str__(self):
        return self.name
class Professor(models.Model):
    teacher = models.OneToOneField(Teacher,primary_key=True,on_delete=models.CASCADE)
    big_project = models.CharField(max_length=50)
    def __str__(self):
        return self.teacher.name
7.2.2 一对一关系的增删改操作
>>> t1 = Teacher.objects.create(name='Jack',age='22')
>>> t2 = Teacher.objects.create(name='Bob',age='17')
>>> p1 = Professor.objects.create(teacher=t1,big_project='雾霾净化术')
>>> p1.teacher
<Teacher: Jack>
>>> p1.teacher = t2
>>> p1.save()

在上面的测试中,看似已经将p1对应的教授变成了Bob;但是在数据库中之前t1老师所对应的教授信息还存在,此时的赋值操作并不会覆盖掉教授他之前的教授数据,只是重新创建了一条。
正确的做法应该是将某一条数据的一对一关系通过delete关系先删除之后再重新赋予

7.2.3 一对一关系正向查询
# 正向查询:通过教授,查询对应的讲师信息
>>> p1.teacher
<Teacher: Bob>
7.2.4 一对一关系反向查询
# 反向查询:通过讲师,查询教授信息, 反向查询时,只需要 模型类 本身即可
t1.professor.name

7.3 多对多关系

7.3.1 什么是多对多关系

多对多关系在模型中使用ManyToManyField字段定义

多对多关系可以是具有关联,也可以是没有关联,所以不需要明确指定on_delete属性

生活中,多对多关系:一个乐队可以有很多音乐家,一个音乐家也可以隶属好多个乐队一个文章中可以有很多标签,一个标签也可出现在很多文章中在多对多关系中专门有第三张表来存储对应关系,表本身之间没有任何关联,此时删除和修改数据不影响另外一张表from

django.db import models
# 一个乐队可以有很多音乐家,一个音乐家也可以隶属好多个乐队
# 定义音乐家模型类
class Artist(models.Model):    
    artist_name = models.CharField(max_length=20,verbose_name="音乐家名字")
    #     定义元类    
    class Meta:        
        db_table = "artist1"    
    def __str__(self):        
        return self.artist_name
    # 定义乐队模型类
    class Band(models.Model):    
        band_name = models.CharField(max_length=20,verbose_name="乐队名")    
        # 多对多    
        artist = models.ManyToManyField(Artist)    
        # 定义元类    
        class Meta:        
            db_table = "band"    
        def __str__(self):        
            return self.band_name
7.3.2 多对多关系为什么不需要on_delete属性
# 在多对多的情况,有专门的第三张表,存储 对应关系, 表本身并没有字段来存储对应关系,此时删除任意数据,不影响另一张表数据
7.3.3 多对多关系的外键添加操作

创建音乐家以及乐队

添加音乐家语法:
    模型类.objects.create()
    a1 = Artist.objects.create(artist_name="朗朗")
    a2 = Artist.objects.create(artist_name="李健")
添加乐队语法:
    语法:
    b1 = Band.objects.create(band_name="破吉他乐队")
    b2 = Band.objects.create(band_name="凯乐乐队")

创建出两个乐队之后对其进行音乐家的添加
多对多字段添加时,可以使用add函数进行多值增加

# b1这个乐队有2个音乐家分别是a1和a2  将a1和a2添加到b1这个乐队里
b1.artist.add(a1,a2)
# b2这个乐队有一个音乐家是a2
b2.artist.add(a2)
7.3.4 多对多关系的外键移除操作

多对多关联字段的删除,要使用remove来进行关系的断开
而不是直接使用deleteremove只会断开数据之间的联系,但是不会将数据删除

在B1乐队中删除A1乐家

# 接触a1和b1的关系   在b1乐队中将a1解除  只是接触乐队和音乐家的关系不是删除数据
b1.artist.remove(a1)
7.3.5 多对多关系的修改和查询
# 通过外键查询该乐队的全部音乐家
# 查看b1乐队的成员
b1.artist.all()
# 查看b2乐队的成员
b2.artist.all()

# 反向查询:通过音乐家,查询该音乐家加入的乐队信息
# 查看a2这个音乐家所属的乐队
a2.band_set.all()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值