django多表关联实战
定义模型类:
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 ##################
# 给出版社表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中
数据库中生成的表结构:




浙公网安备 33010602011771号