数据库关系映射
一、什么是关系映射
在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有:
- 一对一映射如:一个身份证对应一个人
- 一对多映射如:一个班级可以有多个学生
- 多对多映射如:一个学生可以报多个课程,一个课程可以有多个学生学习
二、一对一映射
一对一是表示现实事物间存在的一对一的对应关系。
如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
语法: OneToOneField(类名, on delete=x)
class a(mode l Model):
.....
class b(model. Model):
属性=models.OneToOneField(A, on_delete=xxx)#xxx有以下几种模式
on_delete级联删除
1.models.CASCADEDjango模拟SQL约束ON DELETE CASCADE的行为,并删除包:含ForeignKey的对象。
2.models.PROTECT抛出Protected Error以阻止被引用对象的删除;[等 同于mysql默认的RESTRICT]
3.SET_NULL设置ForeignKey null;需要指定null=True
4 SET_DEFAULT将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
在设置外键约束以后对于被约束对象也在创建和修改时也有了一些约束,如下
无外键的模型类[Author]:
author1= Author.objects.create(ame=王老师)
有外键的模型类[Wife]
wife1= Wife. objects create(name=王夫人, author=author1) #关联王老师obj要先get到对象
wifel= Wife.objects.create(name=王夫人,叫 author_id=1)#关 联王老师对应主键值
突破查询⭐
- 正向查询:直接通关外键属性查询,则称为正向查询
现在是在author表的主键上加了wife的外键
通过wife找author
from.models import wife
wife =wife.objects.get(name='王夫人')
print(wife.name,'的老公是', wife.author.name)
- 反向查询(在表1往表2加外键的时候,表2也会有反向隐藏属性(关联类名的小写形式))
没有外键属性的一方,可以调用反向属性查询到关联的另一方反向关联属性为“实例对象.引用类名(小写),
如作家的反向引用为、作家对象.wife'-当反向引用不存在时,则会触发异常
author1=Author.objects.get(name='王老师')
author1.wife.name
三、一对多映射
一对多是表示现实事物间存在的一对多的对应关系。
如:一个学校有多个班级,一个班级有多个学生,一本图书只能属于一个出版社,一个出版社允许出版多本图书一对多需要明确出具体角色,在多表上设置外键
语法
当一个A类对象可以关联多个B类对象时
class A(model.Model):
...
class B(model.Model):
属性=models.Foreignkey("一"的模型类, on_delete=xx) ###Foreignkey必须指定on-delete模式
正向查询
按照正向查询的定义:多查少就成了正向查询
1. 正向查询[通过Book查询 Publisher]
2. Book objects get(id=1) print( book.title,'的出版社是:', abook.publisher.name)
反向查询
反向查询[通过Publisher查询对应的所有的Book]需要用到反向属性通过出版社查询对应的书
publ = Publisher.objects.get(name='清华大学出版社')
books =pub1.book_set.all() #通过book_set获取pub1对应的多个Book数据对象等同于objects
#books = Book.objects.filter(publisher=pub1) #也可以采用此方式获取
print("清华大学出版社的书有:")for book in books:
print(book.title)
四、多对多映射
多对多表达对象之间多对多复杂关系,如每个人都有不同的学校(小学,初中,高中每个学校都有不同的学生
- mysq|中创建多对多需要依赖第三张表来实现
- Django中无需手动创建第三张表, Django自动完成
语法
- 在关联的两个类中的任意一个类中,增加:
属性= models. ManyToManyField(MyModel)
创建数据的方法
方案1--先创建author再关联book
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再关联author
book = Book.objects.create(title='python1') #郭小闹和吕老师都参与了python1的创作
author3 =book. authors.create (name='guoxiaonao')
book.authors.add (author1)
正向查询
此时属性在book身上所以从book查author是正向查询
1.正向查询有多对多属性的对象 查 另一方
通过Book查询对应的所有的Author
此时多对多属性等价于objects
book.authors.all()->获取book对应的所有的author的信息
book.authors.filter(age_gt=80)->获取book对应的作者中年龄大于80岁的作者的信息
反向查询
2.反向查询
通过Author查询对应的所有的Book利用反向属性bookset
author.book_set.all ()
author.book_set.filter()
Comments NOTHING