三种关系:一对多、多对多、多对一
注意:
- 一对多关系中,外键只能在多表
- 一对一关系中,外键在哪张表无要求,建议放在表数据较少的那张表
- 多对多关系中,外键在哪张表无要求,因为会创建一张新表存储外键关系
准备模型类
```python from django.db import models
Create your models here.
from django.db import models
‘’’ Book —— Publish 一对多 Author —— AuthorDetail 一对一 Author —— Book 多对多 ‘’’
class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField()
# 一对一
authordetail = models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE)
def __str__(self):
return self.name
作者详情表
class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64)
出版社表
class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField()
def __str__(self):
return self.name
class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2)
# 一对多关系(必须放这张表)
publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE, )
'''
publish_id INT ,
FOREIGN KEY (publish_id) REFERENCES publish(id)
'''
# 多对多
authors = models.ManyToManyField(to="Author") # 放在哪个表都行
'''
CREATE TABLE book_authors(
id INT PRIMARY KEY auto_increment ,
book_id INT ,
author_id INT ,
FOREIGN KEY (book_id) REFERENCES book(id),
FOREIGN KEY (author_id) REFERENCES author(id)
)
'''
# class Book2Author(models.Model):
#
# nid = models.AutoField(primary_key=True)
# book=models.ForeignKey(to="Book")
# author=models.ForeignKey(to="Author")
def __str__(self):
return self.title
<a name="rEyev"></a>
## 生成的表
![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611293099898-3d7929a0-5ba8-4f51-b3e3-b386f3d21565.png#height=115&id=e9i0x&margin=%5Bobject%20Object%5D&name=image.png&originHeight=230&originWidth=464&originalType=binary&ratio=1&size=12240&status=done&style=none&width=232)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611374622136-4e662043-f1c5-43b1-8435-adadfcc9a536.png#height=128&id=hsv8G&margin=%5Bobject%20Object%5D&name=image.png&originHeight=256&originWidth=812&originalType=binary&ratio=1&size=23497&status=done&style=none&width=406)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611293484624-3d736986-53e0-40ed-a14e-e596699edf87.png#height=153&id=Vyf89&margin=%5Bobject%20Object%5D&name=image.png&originHeight=305&originWidth=941&originalType=binary&ratio=1&size=35660&status=done&style=none&width=470.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611293437562-0b219d38-a9dd-40f4-a414-0c92f640cd92.png#height=195&id=Hxu1h&margin=%5Bobject%20Object%5D&name=image.png&originHeight=389&originWidth=1254&originalType=binary&ratio=1&size=50979&status=done&style=none&width=627)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611293416745-90f2aec8-ae3e-4713-adb8-ea250c890ba0.png#height=195&id=gDky6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=389&originWidth=742&originalType=binary&ratio=1&size=29499&status=done&style=none&width=371)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12405790/1611374749064-f9afaf04-047d-416c-8a02-9c2b996f9015.png#height=125&id=ssQza&margin=%5Bobject%20Object%5D&name=image.png&originHeight=250&originWidth=749&originalType=binary&ratio=1&size=27997&status=done&style=none&width=374.5)
<a name="K8Grp"></a>
## 添加记录
<a name="RQbKH"></a>
### 表的添加顺序
先添加没有外键的表
```python
pub = Publish.objects.create(name="人民出版社", email="598779784@qq.com", city="北京")
一对多关系添加记录
######################绑定一对多的关系##############################################
#方式1:
#为book表绑定出版社: book --- publish
book_obj=Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
print(book_obj.title)
#方式2:
pub_obj=Publish.objects.filter(nid=1).first()
# publish=pub_obj :会自动翻译成publish_id=1
book_obj=Book.objects.create(title="三国演绎",price=100,publishDate="2012-12-12",publish=pub_obj)
print(book_obj.title)
print(book_obj.price)
print(book_obj.publishDate)
print(book_obj.publish) # 与这本书籍关联的出版社对象
print(book_obj.publish.name)
print(book_obj.publish.email)
print(book_obj.publish_id)
#查询西游记的出版社对应的邮箱
book_obj=Book.objects.filter(title="西游记").first()
print(book_obj.publish.email)
多对多关系添加
######################绑定多对多的关系##############################################
book_obj=Book.objects.create(title="金瓶梅",price=100,publishDate="2012-12-12",publish_id=1)
egon=Author.objects.get(name="egon")
ecithy=Author.objects.get(name="ecithy")
#绑定多对多关系的API
book_obj.authors.add(egon,ecithy) # 通过book_obj、authors找到表book_authors,将egon、ecithy的id取出来放进去
book_obj.authors.add(1,2,3)
book_obj.authors.add(*[1,2,3])
#解除多对多关系
book=Book.objects.filter(nid=4).first()
book.authors.remove(2) # author_id = 2
#book.authors.remove(*[1,2]) # author_id = 1和2
book.authors.clear()
#查询主键为4的书籍的所有作者的名字
book=Book.objects.filter(nid=4).first()
print(book.authors.all()) # [obj1,obj2...] queryset: 与这本书关联的所有作者对象集合
ret=book.authors.all().values("name")
print(ret)