基表多表关系及子序列化

Posted allenchen168

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基表多表关系及子序列化相关的知识,希望对你有一定的参考价值。

class Book(BaseModel):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING, null=True)
    authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)

    def __str__(self):
        return self.name

class Publish(BaseModel):
    name = models.CharField(max_length=64)
    address = models.CharField(max_length=64)

class Author(BaseModel):
    name = models.CharField(max_length=64)

class AuthorDetail(BaseModel):
    mobile = models.CharField(max_length=64)
    author = models.OneToOneField(to=Author, related_name='detail', db_constraint=False, on_delete=models.CASCADE)

基表:

概念:为抽象表,是用来被继承的,提供公有的字段,自身不会完成数据库迁移

在基表中对应的类中写下面两行代码,其他表类继承基表类后数据库迁移才有效。如果不写这两行代码,直接执行数据库迁移命令,继承基表类的其他表中不会生成应有的字段。

class Meta:
    abstract = True

断关联表关系:

优点:

1、不会影响连表查询操作效率

2、会提升连表增删改的操作效率

3、易于后期数据库表的重构

缺点:

1、数据库本身没有连表检测,容易出现脏数据,需要通过严格的逻辑避免脏数据的参数(必要时管理脏数据)

举例:A依赖B,先插入A记录,该记录对应的B记录没产生,在没有关联的情况下,该操作可以实现,但是数据就是脏数据。接着再将B数据添加,脏数据就得到处理了,返过来先操作B后操作A,更满足逻辑思维,一样可以执行。通过逻辑将AB表进行连表查询,不会有任何异常。

表关系:

1、Book 和 Publish 一对多:外键在多的一方 Book中

2、Book 和 Author 多对多: 外键在查询频率高的一方 Book

3、Author 和 AuthorDetail 一对一: 外键在查询频率低的一方更合理

外键字段属性:

1、related_name 在外键中设置外键反向查询的字段名:正向找字段名,反向找related_nema值。

2、on_delete在外键中必须设置,表示级联关系,在Django 1.X下,系统默认提供(值为models.CASCADE), Django 2.X下,必须手动明确。

? CASCADE: 默认值,级联。

? 例子:作者没,详情一定没,存在没意义。

? DO_NOTHING:外键不会被级联,假设A表依赖B表,B记录删除,A表的外键字段不做任何处理。

? 例子:作者没,书还是作者写的;出版社没,书还是该出版社出版的。

? SET_DEFAULT:假设A表依赖B表,B记录删除,A表的外键字段设置为default属性设置的值,所以必须配合default属性使用。

? 例子:部门没,部门员工进入待定部门(注:关联部门表外键可以为空)。

? SET_NULL:假设A表依赖B表,B记录删除,A表的外键字段设置为null,所以必须配合null=True属性使用。

? 注:多对多字段不能设置on_delete级联关系,默认为级联,如果要处理级联关系,需要手动明确关系表,处理关系表中的多个外键

3、db_constraint在外键中控制表关联,默认为True表示关联,设置False表示断开关联(注:该字段只能给Foreignkey进行设置)。

子序列化:

1、只能在序列化中使用,

2、字段名必须是外键字段,

3、在外键关联数据时多条时,

4、需要明确many=True,

5、是单向操作

Tips:只用来展示的长整型数字可以用CharField类型,如电话号码,身份证号。因为它们不会用于计算。

以上是关于基表多表关系及子序列化的主要内容,如果未能解决你的问题,请参考以下文章

ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

数据表关系

子序列化,多表序列化

Django - 模型层 - 下

drf-基表断关联表关系级联删除正方向查询子序列化

android greendao3.0 多表关联关系讲解(转)