基表

抽象基表: 只能被继承, 提供公有字段, 自身不会进行数据库迁移

# 类比auth模块, 从from django.contrib.auth.models import User语句查看User源码, 推出model基表配置方式
class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    created_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True  # 将定义的表配置为抽象基表


class Book(BaseModel):
    pass


class Publish(BaseModel):
    pass

多表断关联

外键断关联:

优点:

  1. 不会影响联表查询操作
  2. 可以提升联表增删改操作效率
  3. 易于后期数据库表的重构

缺点及优化:

  1. 数据库表没有联表检测, 容易出现脏数据
  2. 通过逻辑避免脏数据产生
  3. 必要的时候对脏数据进行统一管理

外键字段属性

  • related_name在外键中设置反向查询的字段名
  • on_delete在外键中设置级联关系, 在django1.x中系统默认为models.CASCADE, 在django2.x中必须手动明确
    • models.DO_NOTHING, 外键不会被级联: 例如作者去世了, 作者写的书籍仍然与其关联
    • models.SET_DEFAULT + defult=..., 级联的外键数据被删除时会将外键值置为默认值: 例如某部门解散后, 该部门所属的员工加入待分部门
    • models.SEt_NULL + null=True, 级联的外键数据被删除时会将外键值置为null
    • 注意: 多对多关系的外键不能设置on_delete, 默认都与关系表中的对应字段为级联删除关系, 除非手动创建关系表
  • db_constraint在外键中控制表关联, 默认为True表示关联, 设置False表示断开关联, 该属性只能给ForeignKey进行设置
'''
...
class Book(BaseModel):
    ...
    publish = models.ForeignKey(to='Publish', related_name='books', on_delete=models.SET_NULL, null=True, db_constraint=False)
    ...


class Publish(BaseModel):
    ...


class Author(BaseModel):
    ...


class AuthorDetail(BaseModel):
    ...
    # 作者详情依赖于作者, 但是作者可以没有作者详情; to参数可以直接写前面已定义过的类名
    author = models.OneToOneField(to=Author, related_name='detail')  # 反向字段
'''

子序列化

  • 子序列化的字段必须是外键, 当外键关联的数据可能有多条时需要明确many=True
  • 子序列化是单向的
  • 导入模块时, 模块所在名称空间中以 _ 开头的变量不对 * 提供
'''
C:\...\d_proj\api\serializers.py
# 多表操作中的子序列化
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__' 


class PublishModelSerializer(serializers.ModelSerializer):
    books = BookModelSerializer(many=True)

    class Meta:
        model = models.Publish
        # fields = '__all__'  # 操作所有字段
        # exclude = ['name']  # 操作除了name以外的字段
        fields = ['name', 'address', 'books']  # 操作指定字段
'''


# C:\...\d_proj\script\a.py
x = 666
_y = 777
__z = 888

__all__ = ['x', '_y', '__z']  # __all__默认只包含名称空间中不以_开头的变量


# C:\...\d_proj\script\test.py
from script.a import *

print(x)
print(_y)
print(__z)