系列文章目录
- Django入门全攻略:从零搭建你的第一个Web项目
- Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
- Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
- Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
- 还在写0.0…
文章目录
- 系列文章目录
- 前言
- 一、多对一关系
- 1.多对一关系是什么
- 2.多对一关系的增删改操作
- 3.多对一的正向查询
- 4.多对一的反向查询
- 二、一对一关系
- 1.一对一关系是什么
- 2.一对一关系的增删改操作
- 3.一对一关系正向查询
- 4.一对一关系反向查询
- 三、多对多关系
- 1.多对多关系是什么
- 2.多对多关系的外键添加操作
- 3.多对多关系的外键移除工作
- 4.多对多关系的修改和查询
前言
在Django开发中,数据关系的管理至关重要。今天,我们将快速了解Django ORM如何处理多对一、一对一和多对多这三种核心数据关系。这些基础知识将帮助你更高效地构建数据库驱动的应用。让我们一起探索Django ORM的奥秘吧!
一、多对一关系
1.多对一关系是什么
Django
使用django.db.models.ForeignKey
定义多对一关系。
博客表—用户表 - - - 多对一
# app/model.py
class UserModel(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
height = models.DecimalField(max_digits=3, decimal_places=2)
def __str__(self):
return self.name
class Meta:
db_table = 'users'
class BlogModel(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
pub_date = models.DateField()
address = models.CharField(max_length=50)
user = models.ForeignKey(to=UserModel, on_delete=models.CASCADE)
def __str__(self):
return self.title
class Meta:
db_table = 'blogs'
2.多对一关系的增删改操作
增:
# 1.添加user
u1 = UserModel.objects.create(name="王五", age=18, height=1.78)
# 2.为 id(pk) = 1的用户添加blog
u2 = UserModel.objects.get(pk=1)
blog = BlogModel()
blog.title = "ORM关联模型"
blog.content = "多对一、一对一、多对多模型"
blog.pub_date = "2024-05-31"
blog.address = "csdn"
blog.user = u2
blog.save()
改:
# 1.修改用户信息
# u3 = UserModel.objects.get(id=1)
# u3.age = 100
# u3.save()
# 2.修改博客信息
# b3 = BlogModel.objects.get(id=9)
# b3.address = "修改后的CSDN地址"
b3 = BlogModel.objects.filter(id=9).update(address="再修改(update)后的CSDN地址")
# b3.save()
删:
# 1.删除blog表中的记录,直接删除
# blog = BlogModel.objects.get(pk=10)
# blog.delete()
# 2.删除user表中数据,此user对应的blog也会删除
u4 = UserModel.objects.get(pk=2)
u4.delete()
3.多对一的正向查询
# 多查询一的情况下,直接通过模型类中的外键关联字段查询
# 正向查询
b5 = BlogModel.objects.get(user_id=1)
print(b5)
print(b5.user.name)
print(b5.user.age)
print(b5.user.height)
>>>ORM关联模型
>>>张安
>>>100
>>>1.96
4.多对一的反向查询
# 反向查询:主表通过blogmodel_set查从表
u6 = UserModel.objects.get(id=1)
print(u6)
b6 = u6.blogmodel_set.all()
print(b6)
for blog in b6:
print(blog.title)
print(blog.content)
二、一对一关系
1.一对一关系是什么
模型类使用
OneToOneField
用来定义一对一关系;
学生表与学生信息表 - - - 一对一
models.CASCADE
:多表关联, 删除数据的时候 一删就全删
#app/model.py
class StudentModel(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
height = models.DecimalField(max_digits=3, decimal_places=2)
def __str__(self):
return self.name
class Meta:
db_table = 'students'
class StuDetail(models.Model):
address = models.CharField(max_length=50)
idcard = models.CharField(max_length=50)
outlook = models.CharField(max_length=50)
student = models.OneToOneField(to=StudentModel, on_delete=models.CASCADE)
def __str__(self):
return self.idcard
class Meta:
db_table = 'detail'
其中,ON DELETE
和 ON UPDATE
表示事件触发限制,各参数意义如下:
参数 | 意义 |
---|---|
RESTRICT | 限制外表中的外键改动(默认值,也是最安全的设置) |
CASCADE | 跟随外键改动 |
SET NULL | 设为null值 |
NO ACTION | 无动作 |
SET DEFAULT | 设为默认值 |
2.一对一关系的增删改操作
增:
# 1.增加学生 Student
st1 = StudentModel()
st1.name = "张三三"
st1.age = 18
st1.height = 1.79
st1.save()
# 2.增加学生信息 StuDetail
sd1 = StuDetail()
sd1.address = "北京"
sd1.idcard = 123
sd1.outlook = '团员'
sd1.student = st1
sd1.save()
改:
# 3.修改 学生详细信息
sd2 = StuDetail.objects.get(id=1)
sd2.address = "我在中东吃炸鸡"
sd2.save()
# 4.修改 学生信息
st2 = StudentModel.objects.get(id=1)
st2.age = 12
st2.save()
删:
# 5.删除
st5 = StudentModel.objects.get(id=1)
st5.delete()
3.一对一关系正向查询
# 5.正向查询:
sd3 = StuDetail.objects.get(id=1)
print(sd3.address)
print(sd3.idcard)
print(sd3.outlook)
print(sd3.student.name)
print(sd3.student.age)
4.一对一关系反向查询
# 6.反向查询:
st4 = StudentModel.objects.get(id=1)
print(st4.name)
print(st4.age)
print(st4.studetail.address)
print(st4.studetail.idcard)
print(st4.studetail.outlook)
#print(stu.blogmodel_set.all())
#注意:这是错误的,一对一没有_set,且全通过小写字段(eg:studetail,blogmodel_set)找到类名
三、多对多关系
1.多对多关系是什么
多对多关系在模型中使用
ManyToManyField
字段定义
多对多关系可以是具有关联,也可以是没有关联,所以不需要明确指定
on_delete
属性
原因:在多对多的情况,有专门的第三张表,存储 对应关系, 表本身并没有字段来存储对应关系,此时删除任意数据,不影响另一张表数据
电影表与演员表 - - - 多对多
# app/models.py
class ActorModel(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
gender = models.CharField(max_length=2)
def __str__(self):
return self.name
class Meta:
db_table = 'actors'
class MovieModel(models.Model):
name = models.CharField(max_length=50)
mtime = models.CharField(max_length=50)
info = models.CharField(max_length=50)
actors = models.ManyToManyField(to=ActorModel)
def __str__(self):
return self.name
class Meta:
db_table = 'movies'
2.多对多关系的外键添加操作
创建:
# 1.添加演员
a1 = ActorModel()
a1.name = '刘海柱'
a1.age = 32
a1.gender = '男'
a1.save()
#
a2 = ActorModel()
a2.name = '赵小刀'
a2.age = 30
a2.gender = '女'
a2.save()
#
a3 = ActorModel()
a3.name = '哈士奇'
a3.age = 33
a3.gender = '男'
a3.save()
-------------------------------------------
# 2.添加电影信息
m1 = MovieModel()
m1.name = "精武门"
m1.mtime = "2h"
m1.info = "这是一个武打片"
m1.save()
m2 = MovieModel()
m2.name = "ye邪不压正"
m2.mtime = "2h30min"
m2.info = "这肯呢个肯呢个可能是一个武打片"
m2.save()
m3 = MovieModel()
m3.name = "don东北黑道纷纭"
m3.mtime = "2h50min"
m3.info = "黄及哦啊哦写"
m3.save()
增加:
# 3.给电影添加演员--正向的
a1 = ActorModel.objects.get(id=1)
a2 = ActorModel.objects.get(id=2)
a3 = ActorModel.objects.get(id=3)
# 给任意一个电影添加对应的演员
m1 = MovieModel.objects.get(id=1)
m1.actors.add(a1)
m1.actors.add(a2)
m1.actors.add(a3)
---------------------------------------------
# 4.给演员安排几个电影拍
m2 = MovieModel.objects.get(id=2)
m3 = MovieModel.objects.get(id=3)
a1 = ActorModel.objects.get(id=1)
a1.moviemodel_set.add(m2,m3)
3.多对多关系的外键移除工作
多对多关联字段的删除,要使用
remove
来进行关系的断开
而不是直接使用delete
,remove
只会断开数据之间的联系,但是不会将数据删除
# 5.删除,会删除电影及电影-演员表中的对应关系
# MovieModel.objects.get(id=1).delete()
# 6.删除对应关系:从某电影m6中移除某演员a1,只影响演员-电影对应关系表
m6 = MovieModel.objects.get(id=6)
a1 = ActorModel.objects.get(id=1)
a1.moviemodel_set.remove(m6)
4.多对多关系的修改和查询
# 7.查询数据
# 根据任意一个电影,查询所有参演的演员-
m1 = MovieModel.objects.get(id=1)
print("-"*10)
print(m1.actors.all())
# 根据任意一个演员,查询拍过的所有电影 f反向查询
a1 = ActorModel.objects.get(id=1)
print("-"*10)
print(a1.moviemodel_set.all())