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中

  

数据库中生成的表结构:

 

 

 

posted @   映辉  阅读(160)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示