关系映射

关系映射

在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有
1.一对一映射
如:一个身份证对应一个人

2.一对多映射
如:一个班级可以有多个学生
3.多对多映射
如: 一个学生可以报多个课程,一个课程可以有多个学生学习

一对一(创建)

一对一是表示现实事物间存在的一对一的对应关系
如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
语法:OneToOneField(类名, on_delete=xxx)

class A(model.Mode1) :
	...
class B(model.Model):
属性 = models.oneTooneField(A,on_delete=xxx)

特殊字段选项[必须]
on_delete - 级联删除

1.models.CASCADE 级联删除。 Django模拟SOL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
2.models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICTI
3.SET_NULL 设置ForeignKey null;  需要指定null=True
4SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值

示例- 创建模型类- oto/models.py

from django.db import models
class Author(models .Mode1):
	"作家模型类"'"
	name = models.CharField('作家,max_length=50)
class wife(models.Mode1):
	''作家妻子模型类''
	name = models.charField("妻子",max_length=50)
	author = models.oneTooneField(Author, on_delete=models.CASCADE) # 增加一对一属性

无外键的模型类[Author]:

author1 = Author.objects.create(name='王老师)

有外键的模型类[Wife

wife1= Wife.objects.create(name='王夫人', author=author1)# 关联王老师obj

wife1 = Wife.objectscreate(name='王夫人', author_id=1)#关联王老师对应主键值
一对一[查询数据]

1.正向查询:直接通关外键属性查询,则称为正向查询

#通过 wife 找 author
from .models import wife
wife = wife.objects.get(name='王夫人')
print(wife.name,的老公是', wife.author.name)

2.反向查询 - 没有外键属性的一方,可以调用反向属性查询到关联的另一方

反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.wife
当反向引用不存在时,则会触发异常

author1 = Author.objects.get(name='王老师')
author1.wifename
一对多 - 创建

语法
当一个A类对象可以关联多个B类对象时

class A(mode1.Mode1) :
	...
class B(mode1.Mode1):
	属性 = models.ForeignKey("一"的模型类,on_delete=xx)
	
ForeignKey必须指定 on_delete模式

示例-创建模型类- otm/models.py

# file: otm/models.pyfrom django.db import models

class Publisher(models .Model) :
	"''出版社[一]''
	name = models.charField('名称',max_length=50, unique=True)
class Book(models .Mode1):
	"书[多]""
	title = models.charField('书名', max_length=50)
	publisher = ForeignKey(PubTisher, on_delete=mode1s.CASCADE)

先创建’一’ 再创建多

from .models import *
pub1 = Publisher.objects.create(name='清华大学出版社')
Book.objectscreate(title='C++', publisher=pub1)
Book.objects.create(title='Java', publisher_id=1)
一对多[查询数据]

1.正向查询[通过Book 查询 Publisher]

通过 publisher 属性查询即可
book.pubTisher
abook = Book.objects.get(id=1)
print(abook.title, '的出版社是:', abook.pubTisher.name)

2.反向查询[通过 Publisher 查询 对应的所有的 Book
需要用到 反向属性

# 通过出版社查询对应的书

pub1 = Publisher.objects.get(name='清华大学出版社')
books = pub1.book set.all() # 通过book_set 获取pub1对应的多个Book数据对象

# books = Book.objects.filter(publisher=pub1)  # 也可以采用此方式获取

print("清华大学出版社的书有:")
for book in books:
	print(book.title)
多对多- 创建

用法示例:
一个作者可以出版多本图书
一本图书可以被多名作者同时编写

class Author(models.Model):
	..
class Book(models.Mode1):
	...
	authors = models.ManyToManyField(Author)

多对多 - 创建数据
方案1 先创建 author 再关联 bookL

author1 = Author.objects.create(name='吕老师')
author2 = Author.objects.create(name='王老师')
# 吕老师和王老师同时写了一本python
book11 = author1.book_set.create(title="python")
author2.book_set.add(book11)

方案2 先创建 book 再关联

authorbook = Book.objects.create(title='python1')
#郭小闹和吕老师都参与了 python1 的 创作
author3 = book.authors.create(name='guoxiaonao')
book.authors.add(author1)
多对多- 查询数据

1,正向查询 有多对多属性的对象查另一方
通过 Book 查询对应的所有的 Author

​ 此时多对多属性等价于 obiects

book.authors.a11() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息

2,反向查询
通过Author 查询对应的所有的Book
利用反向属性 book_set

author.book_set.a11()
author.book_set.fiter()

你可能感兴趣的:(Django,数据库,django)