16 多表設計

1.表設計

'''
BaseModel基表
    is_delete、create_time、orders、updated_time
下面四表繼承基表,能夠繼承兩個字段
    Book表:
        name、price、img、authors、publish
        is_delete、create_time、orders、updated_time
    Publish表:
        name、address
        is_delete、create_time、orders、updated_time
    Author表:
        name、age
        is_delete、create_time、orders、updated_time
    AuthorDetail表:
        mobile, author
        is_delete、create_time、orders、updated_time
'''

2. 基表建立 (注意設置abstract = True)

from django.db import models


class BaseModel(models.Model):
    """公共模型"""
    orders = models.IntegerField(default=1, verbose_name="排序", help_text='排序')
    # 默認不是刪除,數據庫中是0/1
    is_delete = models.BooleanField(default=False, verbose_name="是否刪除", help_text='是否刪除')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="添加時間", help_text='添加時間')
    updated_time = models.DateTimeField(auto_now=True, verbose_name="修改時間", help_text='修改時間')

    class Meta:
        # 設置當前模型爲抽象模型,在數據遷移的時候django就不會爲它單首創建一張表
        abstract = True  # 聲明該表只是一個抽象表不出如今數據庫中

3.斷關聯多表關係

db_constraint=False (設置了這個就是斷關聯,設置在外鍵,刪除了做者詳情,也不會刪除做者)python

3.1 做用

  1. 物理上斷開關係提高查找效率
  2. 防止環裝表關係,致使表關係成爲死表(即不能在操做表,若是想要在從新操做表,須要刪庫)

3.2 字段設計

一、外鍵位置:
	一對多  -- 外鍵放在多的一方
    一對一  —— 從邏輯正反向考慮,如做者表與做者詳情表,做者刪除級聯做者詳情也刪除,詳情刪除做者依舊存在,因此建議外鍵在 詳情表 中
    多對多  -- 外鍵在關係表中
二、ORM正向方向連表查找
	正向:經過外鍵字段 eg:author_detial_obj.author  # 外鍵設置在做者詳情表,在做者詳情表中查詢做者直接 .author就能夠
    反向:經過設置反向查詢related_name的值 eg:author_obj.detail  #外鍵沒有設置在做者表中,在做者表中經過設置反向查詢.detail查詢做者詳情

三、連表操做關係(外鍵建在做者詳情表中)
	1)做者刪除,詳情級聯 - on_delete=models.CASCADE    #跟着一塊兒刪除
    2)做者刪除,詳情置空 - null=True, on_delete=models.SET_NULL   #外鍵字段清空
    3)做者刪除,詳情重置 - default=0, on_delete=models.SET_DEFAULT
    4)做者刪除,詳情不動 - on_delete=models.DO_NOTHING

4.模型表設計

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)  # 默認不是刪除,數據庫中是0/1
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='建立時間')

    # 設置 abstract = True 來聲明基表,做爲基表的Model不能在數據庫中造成對應的表
    class Meta:
        abstract = True  # 聲明該表只是一個抽象表不出如今數據庫中


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')

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

    @property
    def publish_name(self):
        return self.publish.name

    @property
    def authorlist(self):
        return self.authors.values('name', 'age', 'detail__mobile').all()

    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)
    addres = 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, author、is_delete、create_time"""
    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 self.author.name
相關文章
相關標籤/搜索