django多表关联实战
定义模型类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | from django.db import models from django.contrib.auth.models import User ''' ---------- Django-ORM多表关联 ---------- ''' ''' 需要创建的表: 1. 书籍表 2. 出版社表 3. 作者表 4. 作者详情表 ''' ''' 表的对应关系: --- 一个出版社可以出版多本书籍 (一对多) --- 书籍和作者多对多 (多对多) --- 每个作者只能对应一个作者详情 (一对一) ''' # 1. 书籍表 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" , related_name = "booklist" , on_delete = models.CASCADE) ''' publish: 字段名,表示书籍所属的出版社 与出版社表(Publish表)建立一对多的关系,外键建立在多的一方 to="Publish": 指定要关联的表 to_field="nid": 指定要关联的字段(如果不指定,则默认关联主键) on_delete=models.CASCADE: 表示删除主键以后,外键对应的数据也被删除 related_name: 反向查找字段 ''' authors = models.ManyToManyField(to = "Author" , related_name = "booklist" , db_table = "tb_book_author" ) ''' authors: 作者字段,与作者表Author建立多对多的关系,ManyToManyField可以在任意一方 to="Author": 指定要关联的表 db_table="tb_book_author": 多对多关系会生成第三张表,通过第三张表进行关联, 通过 db_table=xxx 指定第三张表的表名, 第三张表会生成三个字段:id、book_id、author_id ''' class Meta: db_table = "tb_book" # 2. 出版社表 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() # 邮箱 class Meta: db_table = "tb_publish" # 3. 作者表 class Author(models.Model): nid = models.AutoField(primary_key = True ) name = models.CharField(max_length = 32 ) age = models.IntegerField() authorDetail = models.OneToOneField(to = "AuthorDetail" , on_delete = models.CASCADE) ''' authorDetail: 作者详情,与作者详情表AuthorDetail建立一对一的关系 to="AuthorDetail": 指定一对一关联的表 ''' class Meta: db_table = "tb_author" # 4. 作者详情表 class AuthorDetail(models.Model): nid = models.AutoField(primary_key = True ) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length = 64 ) class Meta: db_table = "tb_authordetail" |
表操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | ################## 1 ################## # 给出版社表Publish中添加记录,用常规方式添加即可: # Publish.objects.create(name="西安出版社", city="西安", email="123@qq.com") ################## 2 ################## # 一对多添加记录:给Book书籍表中添加出版社 # 方式1:先找到对应的出版社对象,然后在书籍中添加这个出版社对象 # pub_obj = Publish.objects.get(pk=1) # Book.objects.create(title="西游记", price=120, publishDate="2020-12-03", publish=pub_obj) # 方式2:直接在书籍表中添加对应出版社的id # Book表的出版社字段在模型类中为publish,但是在数据库表中生成的字段名为:publish_id # Book.objects.create(title="红楼梦", price=110, publishDate="2020-11-03",publish_id=1) ################## 3 ################## # 一对一添加记录:添加记录的方式与上面一对多的方式相同 ################## 4 ################## # 多对多添加记录:给Book书籍添加作者 # 方式1:先获取作者的模型类对象,然后将这个对象添加到对应的书籍Book对象中 # 获取作者对象: # tom = Author.objects.get(name="tom") # jack = Author.objects.get(name="jack") # 获取书籍对象: # book = Book.objects.get(nid=1) # 给book书籍添加tom, jack两个作者, 添加后可以通过中间表(即第三张表)关联书籍和作者 # book.authors.add(tom, jack) # 方式2:直接将作者的 id 添加到书籍对象中即可 # 获取需要添加作者的书籍: # book = Book.objects.get(nid=1) # 给这个书籍添加作者(给book书籍添加id==1和id==2的作者) # book.authors.add(1, 2) ################## 5 ################## # 一对多查询:要查询某一本书的出版社 # 方式1: 通过数据库中生成的字段publish_id查询,但是只能查询出表中publish_id的值 # book = Book.objects.get(pk=1) # print(book.publish_id) // 结果为 1 # 方式2:通过book.publish查询,可以直接查询出book对象对应的出版社的对象(此处的publish为模型类中定义的属性) # book = Book.objects.get(pk=1) # print(book.publish) // 结果为:Publish object (1) ################## 6 ################## # 多对多查询:要查询书籍对应的所有作者 # book = Book.objects.get(pk=1) # authors = book.authors.all() # 查询book书籍对象的所有作者 # print(authors) # 返回一个QuerySet对象 # 结果:<QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]> ################## 7 ################## # 多对多关联表 ---- 删除记录: # book = Book.objects.get(pk=2) # 先找到需要操作的书籍对象book # book.authors.remove(1) # 在书籍book中删除掉id=1的这个作者 # book.authors.clear() # 在书籍book中删除掉所有的作者 # book.authors.set([1,]) # set() 等价于先clear(), 再add(), 即:先删除所有作者,再添加id=1的作者到book中 |
数据库中生成的表结构:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?