三种关系:一对多、多对多、多对一
注意:

  • 一对多关系中,外键只能在多表
  • 一对一关系中,外键在哪张表无要求,建议放在表数据较少的那张表
  • 多对多关系中,外键在哪张表无要求,因为会创建一张新表存储外键关系

    准备模型类

    ```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()

  1. # 一对一
  2. authordetail = models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE)
  3. def __str__(self):
  4. 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()

  1. def __str__(self):
  2. 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)

  1. # 一对多关系(必须放这张表)
  2. publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE, )
  3. '''
  4. publish_id INT ,
  5. FOREIGN KEY (publish_id) REFERENCES publish(id)
  6. '''
  7. # 多对多
  8. authors = models.ManyToManyField(to="Author") # 放在哪个表都行
  9. '''
  10. CREATE TABLE book_authors(
  11. id INT PRIMARY KEY auto_increment ,
  12. book_id INT ,
  13. author_id INT ,
  14. FOREIGN KEY (book_id) REFERENCES book(id),
  15. FOREIGN KEY (author_id) REFERENCES author(id)
  16. )
  17. '''
  18. # class Book2Author(models.Model):
  19. #
  20. # nid = models.AutoField(primary_key=True)
  21. # book=models.ForeignKey(to="Book")
  22. # author=models.ForeignKey(to="Author")
  23. def __str__(self):
  24. return self.title
  1. <a name="rEyev"></a>
  2. ## 生成的表
  3. ![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)
  4. <a name="K8Grp"></a>
  5. ## 添加记录
  6. <a name="RQbKH"></a>
  7. ### 表的添加顺序
  8. 先添加没有外键的表
  9. ```python
  10. pub = Publish.objects.create(name="人民出版社", email="598779784@qq.com", city="北京")

一对多关系添加记录

  1. ######################绑定一对多的关系##############################################
  2. #方式1:
  3. #为book表绑定出版社: book --- publish
  4. book_obj=Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
  5. print(book_obj.title)
  6. #方式2:
  7. pub_obj=Publish.objects.filter(nid=1).first()
  8. # publish=pub_obj :会自动翻译成publish_id=1
  9. book_obj=Book.objects.create(title="三国演绎",price=100,publishDate="2012-12-12",publish=pub_obj)
  10. print(book_obj.title)
  11. print(book_obj.price)
  12. print(book_obj.publishDate)
  13. print(book_obj.publish) # 与这本书籍关联的出版社对象
  14. print(book_obj.publish.name)
  15. print(book_obj.publish.email)
  16. print(book_obj.publish_id)
  17. #查询西游记的出版社对应的邮箱
  18. book_obj=Book.objects.filter(title="西游记").first()
  19. print(book_obj.publish.email)

多对多关系添加

  1. ######################绑定多对多的关系##############################################
  2. book_obj=Book.objects.create(title="金瓶梅",price=100,publishDate="2012-12-12",publish_id=1)
  3. egon=Author.objects.get(name="egon")
  4. ecithy=Author.objects.get(name="ecithy")
  5. #绑定多对多关系的API
  6. book_obj.authors.add(egon,ecithy) # 通过book_obj、authors找到表book_authors,将egon、ecithy的id取出来放进去
  7. book_obj.authors.add(1,2,3)
  8. book_obj.authors.add(*[1,2,3])
  9. #解除多对多关系
  10. book=Book.objects.filter(nid=4).first()
  11. book.authors.remove(2) # author_id = 2
  12. #book.authors.remove(*[1,2]) # author_id = 1和2
  13. book.authors.clear()
  14. #查询主键为4的书籍的所有作者的名字
  15. book=Book.objects.filter(nid=4).first()
  16. print(book.authors.all()) # [obj1,obj2...] queryset: 与这本书关联的所有作者对象集合
  17. ret=book.authors.all().values("name")
  18. print(ret)