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
相关文章
相关标签/搜索