目录
数据表关联关系映射
常用的表关联方式有三种:
一对一映射
如: 一个身份证对应一个人
一对多映射
如: 一个班级可以有多个学生
多对多映射
如: 一个学生可以报多个课程,一个课程可以有多个学生学习
一对一映射
- 一对一是表示现实事物间存在的一对一的对应关系。
- 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
语法
class A(model.Model): ... class B(model.Model): 属性 = models.OneToOneField(A, on_delete=xxx)
外键类字段选项
特殊字段参数【必须项】:
on_delete
- models.CASCADE 级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
- models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICT]
- models.SET_NULL 设置ForeignKey null;需要指定null=True
- models.SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
- … 其它参请参考文档 https://docs.djangoproject.com/en/2.2/ref/models/fields/#foreignkey
其余常用的字段选项【非必须项】;如:
- null
- unique 等
用法示例
创建作家和作家妻子类
# file : xxxxxxxx/models.py from django.db import models class Author(models.Model): \'\'\'作家模型类\'\'\' name = models.CharField(\'作家\', max_length=50) class Wife(models.Model): \'\'\'作家妻子模型类\'\'\' name = models.CharField(\"妻子\", max_length=50) author = models.OneToOneField(Author, on_delete=models.CASCADE) # 增加一对一属性
创建一对一的数据记录
from .models import * author1 = Author.objects.create(name=\'王老师\') wife1 = Wife.objects.create(name=\'王夫人\', author=author1) # 关联王老师 author2 = Author.objects.create(name=\'小泽老师\') # 一对一可以没有数据对应的数据
数据查询
正向查询
直接通过关联属性查询即可
# 通过 wife 找 author from .models import Wife wife = Wife.objects.get(name=\'王夫人\') print(wife.name, \'的老公是\', wife.author.name)
反向查询
- 通过反向关联属性查询
- 反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.wife
- 当反向引用不存在时,则会触发异常
# 通过 author.wife 关联属性 找 wife,如果没有对应的wife则触发异常 author1 = Author.objects.get(name=\'王老师\') print(author1.name, \'的妻子是\', author1.wife.name) author2 = Author.objects.get(name=\'小泽老师\') try: print(author2.name, \'的妻子是\', author2.wife.name) except: print(author2.name, \'还没有妻子\')
一对多映射
- 一对多是表示现实事物间存在的一对多的对应关系。
- 如:一个学校有多个班级,一个班级有多个学生, 一本图书只能属于一个出版社,一个出版社允许出版多本图书
语法
当一个A类对象可以关联多个B类对象时
class A(model.Model): ... class B(model.Model): 属性 = models.ForeignKey(\"一\"的模型类, on_delete=xx)
用法示例
有二个出版社对应五本书的情况.
清华大学出版社 有书
- C++
- Java
- Python
北京大学出版社 有书
- 西游记
- 水浒
创建模型类
# file: otm/models.py from django.db import models class Publisher(models.Model): \'\'\'出版社【一】\'\'\' name = models.CharField(\'名称\', max_length=50, unique=True) class Book(models.Model): \'\'\'书【多】\'\'\' title = models.CharField(\'书名\', max_length=50) publisher = ForeignKey(Publisher, on_delete=models.CASCADE)
创建数据
#先创建 \'一\' ,再创建 \'多\' from .models import * pub1 = Publisher.objects.create(name=\'清华大学出版社\') Book.objects.create(title=\'C++\', publisher=pub1) Book.objects.create(title=\'Java\', publisher_id=1) #高级创建 - 利用 反向属性 pub2 = Publisher.objects.create(name=\'北京大学出版社\') pub2.book_set.create(title=\'西游记\')
数据查询
通过 Book 查询 Publisher【正向】
通过 publisher 属性查询即可 book.publisher abook = Book.objects.get(id=1) print(abook.title, \'的出版社是:\', abook.publisher.name)
通过 Publisher 查询 对应的所有的 Book 【反向】
Django会在Publisher中增加一个属性来表示对对应的Book们的查询引用
属性:book_set 等价于 objects
# 通过出版社查询对应的书 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)
多对多映射
多对多表达对象之间多对多复杂关系,如: 每个人都有不同的学校(小学,初中,高中,…),每个学校都有不同的学生…
语法
在关联的两个类中的任意一个类中,增加:
属性 = models.ManyToManyField(MyModel)
用法示例
- 一个作者可以出版多本图书
- 一本图书可以被多名作者同时编写
class Author(models.Model): ... class Book(models.Model): ... authors = models.ManyToManyField(Author)
创建模型类
class Author(models.Model): \'\'\'作家模型类\'\'\' name = models.CharField(\'作家\', max_length=50) def __str__(self): return self.name class Book(models.Model): \'\'\'书模型类\'\'\' title = models.CharField(\'书名\', max_length=50) authors = models.ManyToManyField(Author) def __str__(self): return self.title
创建数据
方案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 查询对应的所有的 Author【正向】
book.authors.all() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息
通过 Author 查询对应的所有的Book【反向】
Django会生成一个反向属性 book_set 用于表示对对应的book的查询对象相关操作
author.book_set.all() author.book_set.filter()
© 版权声明
THE END
暂无评论内容