一、基表
- 基表是一种抽象类,专门用来被继承,提供公有字段的,执行迁移命令时自身不会完成数据库迁移
- 通过在类中定义Meta配置类,再Meta中定义abstract=True来表示这是一个基类
from django.contrib.auth.models import User
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
created_time = models.DateTimeField(auto_now_add=True)
class Meta:
# 基表,为抽象表,是专门用来被继承,提供公有字段的,自身不会完成数据库迁移
abstract = True
二、ORM表关系补充
一对多:Book和Publish表,外键建立在查询频率高的一方(Book表)
多对多:Book和Author表,外键建立在查询频率高的一方(Book表)
一对一:Author和AuthorDetail表,外键要根据实际情况建立在合理的一方(AuthorDetail表)
必须要先删除依赖表中数据,对应的被依赖表中数据才可以被删除
作者可以没有对应详细信息,但是详细信息表必须要有对应的作者,因此应该外键字段建立在详细信息表中
三、外键字段属性补充
(一)related_name
- 通过被依赖的表反向查询时可以通过该属性设置的字段名找到对应的表名
- 正向找字段名,反向找related_name
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')
# Publish表中数据对象可以通过publish_obj.books找到对应关联Book表的数据对象
(二)on_delete
- 该属性表示级联删除,设置后,可以直接删除被依赖表中数据,依赖表中数据变化根据属性值有四种(只能用于ForeignKey和OneToOneField)
- models.CASCADE:默认值,级联关系,被依赖表删除时,依赖表对应数据也会被删除
- DO_NOTHING:外键不会被级联,被依赖表删除时,依赖表中外键字段不变
- SET_DEFAULT:需要配合default属性使用,被依赖表删除时,依赖表中外键字段值变为default设置的默认值
- SET_NULL:配合null=True使用,被依赖表删除时,依赖表中的外键字段值变为空
- 通过ManyToManyField绑定的多对多字段不能设置on_delete级联关系,只能通过新建第三张表,通过ForeignKey绑定的字段才可以设置
- Django1.x版本中,系统默认提供(值为models.CASCADE)
- Django2.x中,必须手动明确
class Book(BaseModel):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=10, decimal_places=2)
Publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
(三)db_constraint
- 在外键中控制表关联,默认为True表示关联,设置False表示断开关联
- 断开关联时,在创建数据时,就不会受到外键关系的约束
- 实际上,断开关联在MySQL层面就是建立两个没有外键约束,毫不相干的两个表,只是在ORM层面在查询时通过逻辑将两个表建立了联系
class Book(BaseModel):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=10, decimal_places=2)
publish = models.ForeignKey(to='Publish', db_constraint=False)
authors = models.ManyToManyField(to='Author', db_constraint=False)
四、子序列化(序列化补充)
- 只能序列化中使用
- 字段名必须是外键字段,正向反向均可
- 自定义序列化字段是不能参与反序列化,而子序列化必须是自定义序列化字段(外键名),所以就无法入库
- 外键关联数据是多条时,需要明确many=True
- 子序列的类必须写在上方,是一种单向操作
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__'
fields = ['name', 'address', 'books']