迁移
- 分两步实现
- 生成迁移文件
- 执行迁移文件
- 迁移文件的生成
- 根据models文件生成对应的迁移文件
- 根据models和已有迁移文件差别生成新的迁移文件
- 执行迁移文件
- 前去迁移记录中查找那些文件未迁移过
- app_label + 迁移文件名字
- 执行未迁移的文件
- 执行完毕,记录执行过的迁移文件
- 前去迁移记录中查找那些文件未迁移过
- 重新迁移
- 删除迁移文件
- 删除迁移文件产生的表
- 删除迁移记录
模型关系
-
1:1
-
应用场景
- 用于复杂表的拆分
- 扩展新功能
-
Django中的OneToOneField
- 使用时,关系声明还是有细微差别
-
实现
- 使用外键实现的
- 对外键添加了唯一约束
-
数据删除
-
级联表
- 主表
- 从表:声明关系的是从表
- 当系统遭遇不可避免毁灭时,只能保留一张表,这张表就是你的主表
-
默认特性(CASECADE)
-
从表数据删除,主表不受影响
-
主表数据删除,从表数据直接删除
-
class IDCard(models.Model): id_num = model.CharField(max_length=18, unique=True) # on_delete=models.PROTECT 当IDCard未删除时保护person不被删除 # on_delete=models.SET_NULL 允许为NULL # on_delete=models.SET_DEFAULT 存在默认值 id_person = models.OneToOneField(Person, null=True, blank=True, on_delete=models.PROTECT)
-
PROTECT受保护
- 开发中为了防止误操作,我们通常会设置为此模式
- 主表如果存在级联数据,删除动作受保护,不能成功
- 如果主表不存在级联数据,可以删除成功
-
级联数据获取
- 主获取从 隐形属性 默认就是级联模型的名字
- 从获取主 显性属性 就是属性的名字
-
-
-
-
1:N
- ForeignKey
- 主从获取
- 主获取从 隐性属性 级联模型_set
- student_set Manager的子类
- all
- filter
- exclude
- Manager上能使用的函数就都能使用
- student_set Manager的子类
- 从获取主
- 显性属性
- 主获取从 隐性属性 级联模型_set
-
M:N
-
实际上最复杂
-
开发中很少直接使用多对多属性,而是自己维护多对多的关系
-
class Goods(models.Model): g_name = models.CharField(max_length=16) g_customer = models.ManyToManyField(Customer)
-
产生表的时候会产生单独的关系表
- 关系表中存储关联表的主键,通过多个外键实现的
- 多个外键值不能同时相等
-
级联数据
-
add
-
remove
-
clear
-
set级联数据获取
-
从获取主
-
使用属性,属性是一个Manager子类
def add_to_cart(request): customer = Customer.object.last() goods = Goods.object.last() goods.g_customer.add(customer) #新增关联数据 # goods.g_customer.remove(customer) #删除关联数据
-
-
主获取从
-
隐性属性
def add_to_cart(request): customer = Customer.object.last() goods = Goods.object.last() customer.goods_set.add(goods) #新增关联数据 # customer.goods_set.remove(goods) #删除关联数据
- 也是Manager子类,主操作从和从操作主完全一样
-
-
-
-
ManyRelatedManager
- 函数中定义的类
- 并且父类是一个参数
- 动态创建
Models的面向对象
-
django中的数据库模块提供了一个非常不错的功能,就是支持models的面向对象,可以在models中添加meta,指定是否抽象,然后进行继承
-
Django中模型支持继承
-
默认继承是会将通用字段放到父表中,特定字段放在自己的表中,中间使用外键连接
- 关系型数据库关系越复杂,效率越低,查询越慢
- 父类表中也会存在过多的数据存储,导致效率低下
-
使用元信息来解决此问题
- 使模型抽象化
- 抽象的模型就不会在数据库中产生映射了
- 子模型映射出来的表直接包含父模型的字段
-
在meta类中使用abstract = True可以避免创建Animal表
-
model
class Animal(models.Model): a_name = models.CharField(max_length=16) class Meta: abstract = True #避免创建Animal表 class Cat(Animal): c_eat = models.CharField(max_length=32) class Dog(Animal): d_lets = models.IntegerField(default=4)
-
view
def add_cat(request): cat = Cat() cat.a_name = "Tom" cat.c_eat = "Fish" cat.save() return ---
在企业开发中
- model => sql
- 直接使用model创建
- sql => model
- Django也提供了良好的支持
- 调用:
- 删除models文件
- python manage.py inspectdb > App/models.py
- 可以直接根据表生成模型
- 元信息中包含一个属性 manage=False
- 如果自己的某个模型不想被迁移系统管理,也可以使用manage=False进行声明