当前位置:网站首页>P3 元宝第七单元笔记
P3 元宝第七单元笔记
2022-07-30 05:40:00 【YuanBao717】
第七单元 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的学生的老师姓名
--找到id为2的学生
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来进行关系的断开
而不是直接使用delete,remove只会断开数据之间的联系,但是不会将数据删除
在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()
边栏推荐
猜你喜欢

2022 SQL big factory high-frequency practical interview questions (detailed analysis)

More fragrant open source projects than Ruoyi in 2022

navicat无法连接mysql超详细处理方法

Solve the problem that the local nacos is not configured but the localhost8848 connection exception always occurs

零基础C语言“函数”教程,有手就行

Qt在QTableWidget、View等表格中添加右击菜单

torch.load()

208.实现Trie树(字典树与哈希表实现)

MySQL fuzzy query performance optimization

Anaconda安装教程
随机推荐
留念 · 大学时代最后的系统设计图
安装Nuxt.js时出现错误:TypeError:Cannot read property ‘eslint‘ of undefined
Qt实现单击或双击QTableWidge/View表头进行排序
650.只有两个键的键盘(动态规划)
4461. Range Partition (Google Kickstart2022 Round C Problem B)
HCIP-第九天-BGP(边界网关协议)
Anaconda安装教程
每日练习------输出一个整数的二进制数、八进制数、十六进制数。
0基础玩转C语言—初识C语言(上)
微积分 / 自动求导
5.5线程池
[详解C语言]一文带你玩转数组
My first understanding of MySql, and the basic syntax of DDL and DML and DQL in sql statements
How is crawler data collected and organized?
SRA数据下载方法总结
384.打乱数组
MySql fuzzy query Daquan
ClickHouse data insert, update and delete operations SQL
Graphic mirror symmetry (schematic diagram)
2022 SQL big factory high-frequency practical interview questions (detailed analysis)