分享

python_Django中的关系映射

 风声之家 2022-02-17

amberli 程序员的IT之旅 2022-01-30 09:38

图片

Django中的关系映射

什么是关系映射?
在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有:
1. 一对一映射
如:一个身份证对应一个人
2. 一对多映射
如:一个班级可以有多个学生
3. 多对多映射
如:一个学生可以报多个课程,一个课程可以有多个学生学习

一对一:
一对一是表示现实事物间存在的一对一的对应关系
语法:OneToOneField(类名,on_delete=xxx)
class A(model.Model):
...
class B(model.Model):
属性 = models.OneToOneField(A, on_delete=xxx)
特殊字段选项【必须】
on_delete: 级联删除
1. models.CASCADE 级联删除。Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象
2. models.PROTECT 抛出ProtectedError以阻止被引用对象的删除;(等同于mysql默认的RESTRICT)
3. SET_NULL 设置ForeignKey null;需要指定null=True
4. SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值

eg:
class Author(models.Model):
name = models.CharField("姓名", max_length=11)

class Wife(models.Model):
name = models.CharField("姓名", max_length=11)
author = models.OneToOneField(Author, on_delete=models.CASCADE)
一对一创建数据
无外键的模型类[Author]:
author1 = Author.objects.create(name="王老师")
有外键的模型类[Wife]
wife1 = Wife.objects.create(name="王夫人",author=author1) # 关联王老师obj
or
wife1 = Wife.objects.create(name="王夫人",author_id=1) # 关联王老师对应主键
>>> from oto.models import *
>>> author = Author.objects.create(name="王老师")
>>> wife = Wife.objects.create(name="王夫人", author=author)
>>> author2 = Author.objects.create(name="李老师")
>>> wife2 = Wife.objects.create(name="李夫人", author_id=2)

一对一查询数据
1.正向查询:直接通过关联外键属性查询,则称为正向查询
# 通过wife找author
from .models import Wife
wife = Wife.objects.get(name="王夫人")
print(f"{wife.name}的老公是:{wife.author.name}")
2.反向查询:没有外键属性的一方,可以调用反向属性查询到关联的另一方
反向关联属性为 实例对象.引用类名(小写),如作家的反向引用为 作家对象.wife
当反向引用不存在时,则会触发异常
author1 = Author.objects.get(name="王老师")
author1.wife.name

一对多:
一对多是表示现实事物间存在的一对多的对应关系
一对多需要明确出具体角色,在多的表上设置外键
语法:
当一个A类对象可以关联多个B类对象时
class A(model.Model):
...
class B(model.Model):
属性 = models.ForeignKey("一"的模型类, on_delete=xxx)
ForeignKey必须指定on_delete模式
一对多创建数据
先创建'一'再创建'多'
from .models import *
pub1 = Publisher.objects.create(name="武汉大学出版社")
Book.objects.create(title="python",publisher=pub1)
or
Book.objects.create(title="django",publisher_id=1)
一对多查询数据
1.正向查询[通过Book查询Publisher]
通过 publisher 属性查询即可
book.publisher
book = Book.objects.get(id=1)
print(f"{book.title}的出版社是:{book.publisher.name}")
2.反向查询[通过Publisher查询对应的所有的Book]
需要用到反向属性
# 通过出版社查询对应的书
pub1 = Publisher.objects.get(name="武汉大学出版社")
books = pub1.book_set.all() # 通过book_set获取pub1对应的多个Book数据对象
# books = Book.objects.filter(publisher=pub1) # 也可以采用此种方式获取

多对多
多对多表达对象之间多对多复杂关系
mysql中创建多对多需要依赖第三张表来实现
django中无需手动创建第三张表,django自动完成
语法:
属性=models.ManyToManyField(MyModel)
eg:
一个作者可以出版多本图书
一本图书可以被多名作者同时编写
class Author(models.Model):
...
class Book(models.Model):
...
authors = models.ManyToManyField(Author)
多对多创建数据
方案1 先创建 author 再关联 book
author1 = Author.objects.create(name="amber")
author2 = Author.objects.create(name="amberli")
# amber和amberli同时写了一本python
book1 = author1.book_set.create(title="python")
author2.book_set.add(book1)
方案2 先创建 book 再关联 author
book = Book.objects.create(title="python3")
# amberlee和amberli都参与了 python3的创作
author3 = book.authors.create(name="amberlee")
book.authors.add(author2)
多对多查询数据
1.正向查询 有多对多属性的对象 查 另一方
通过Book查询对应的所有的Author
此时多对多属性 等价于 objects
book.authors.all() # 获取book 对应的所有的author的信息
book.authors.filter(name="amber") # 获取book对应的作者中名字为amber的作者信息
2.反向查询
通过Author查询对应的所有的Book
利用反向属性book_set
author.book_set.all()
author.book_set.filter()

确定

  • 不看此公众号

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多