DRF框架(六)——多表關係設計

BaseModel基表 models.py

# 基表
class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False) #默認不是刪除,數據庫中是0/1
    create_time = models.DateField(auto_now_add=True)

    # 作爲基表的model不能在數據庫中形成對應的表,設置abstract = True
    class Meta:
        abstract = True #聲明該表只是一個抽象表不出現在數據庫中

繼承基表 models.py

# 書籍表
class Book(BaseModel):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    img = models.ImageField(upload_to='img', default='img/default.jpg')
    # 關聯出版社表
    publish = models.ForeignKey(
        to='Publish', # 關聯publish表
        db_constraint=False, #斷關聯(斷開Book表和Publish表的關聯,方便刪數據,雖然斷開了關聯但是還能正常使用
        related_name='books', # 反向查詢字段:publish_obj.books就能查出當前出版社出版的所有書籍
        on_delete=models.DO_NOTHING, # 設置連表操作關係
    )
    # 關聯作者表
    authors = models.ManyToManyField(
        to='Author',
        db_constraint=False, #斷開關聯
        related_name='books' #反向查詢字段
    )

    class Meta:
        db_table = 'book'
        verbose_name = '書籍'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 出版社表
class Publish(BaseModel):
    name = models.CharField(max_length=64)
    address = models.CharField(max_length=64)

    class Meta:
        db_table = 'publish'
        verbose_name = '出版社'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 作者表
class Author(BaseModel):
    name = models.CharField(max_length=64)
    age = models.IntegerField()

    class Meta:
        db_table = 'author'
        verbose_name = '作者'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 作者詳情表
class AuthorDetail(BaseModel):
    mobile = models.CharField(max_length=11)
    author = models.OneToOneField(
        to='Author',
        db_constraint=False,
        related_name='detail',
        on_delete=models.CASCADE)

    class Meta:
        db_table = 'author_detail'
        verbose_name = '作者詳情'
        verbose_name_plural = verbose_name
    def __str__(self):
        return '%s的詳情' % self.author.name

 

多表關係斷聯 db_constraint=False

1、外鍵位置:

一對多關係 —— 外鍵放在多的一方

一對一關係 —— 從邏輯正反向考慮

  • 如作者表與作者詳情表,作者刪除級聯作者詳情也刪除,詳情刪除作者依舊存在,所以建議外鍵在詳情表中

多對多關係 —— 外鍵在關係表中

 

2、ORM正向方向連表查找:

正向:通過外鍵字段 eg: author_detial_obj.author

  • 外鍵設置在作者詳情表,在作者詳情表中查詢作者直接.author就可以

反向:通過設置反向查詢related_name的值 eg: author_obj.detail

  • 外鍵沒有設置在作者表中,在作者表中通過設置反向查詢.detail查詢作者詳情

 

3、連表操作關係:(外鍵在作者詳情表中)

  • 作者刪除,詳情級聯 —— on_delete=models.CASCADE # 跟着一起刪除
  • 作者刪除,詳情置空 —— on_delete=models.SET_NULL #外鍵字段清空
  • 作者刪除,詳情重置 —— on_delete=models.SET_DEFAULT
  • 作者刪除,詳情不動 —— on_delete=models.DO_NOTHING

4、外鍵關聯字段的參數 

  • ManyToManyField不能設置on_delete

  • OneToOneField、ForeignKey必須設置on_delete

  • Django1.x系統默認級聯,但是Django2.X必須手動明確

作者詳情表

author = models.OneToOneField(
    to='Author', #和作者表關聯
    db_constraint=False, #範查詢,作者表直接查作者詳情表的電話號碼,可以直接author_obj.detail.mobile
    related_name='detail', #斷關聯
    on_delete=models.CASCADE
)

圖書表

    # 關聯出版社表
    publish = models.ForeignKey(
        to='Publish', # 關聯publish表
        db_constraint=False, #斷關聯(斷開Book表和Publish表的關聯,方便刪數據,雖然斷開了關聯但是還能正常使用
        related_name='books', # 反向查詢字段:publish_obj.books就能查出當前出版社出版的所有書籍
        on_delete=models.DO_NOTHING, # 設置連表操作關係
    )

    # 關聯作者表
    authors = models.ManyToManyField(
        to='Author',
        db_constraint=False,
        related_name='books'
    )

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章