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中

  

数据库中生成的表结构:

 

 

 

posted @ 2023-05-28 18:27  映辉  阅读(185)  评论(0)    收藏  举报