静态网站转成动态网站/长尾关键词挖掘精灵官网
背景知识
最近开发的一个项目中用到模型快照刚开始准备用 Django 模型做,于是查看了 Django 模型继承的几种方式,由于该项目只是使用 Django 作为后台管理并没有直接生成迁移文件定义数据库。最后这些模型继承方案都未被采用但是这里还是需要总结记录。
Django 模型继承的三种方式
抽象继承
抽象继承:创建一个通用的父类,但是我们并不想父类被创建,但是继承该父类的子类都有该抽象父类的字段。在抽象父类的 Meta 中设置 abstract=true 即可实现。
应用场景举例:
我们有两个模型 Book 、Author 这两个模型我们都需要 createdAt 以及 updatedAt 以及 enable 字段,如果我们每个模型都定义一次这样会显得有点冗余,这里可以采用抽象模型继承的方式,我们定义一个父类包含 createdAt 以及 updatedAt 以及 enable 字段 Book、Author 这两个类去继承该父类即可
from django.db import models# 定义父类抽象类
class Base(models.Molde):createdAt = models.BigIntegerField(verbose_name='创建时间')updatedAt = models.BigIntegerField(verbose_name='更新时间')enable = models.BooleanField(verbose_name='是否可用')class Meta:# 表示该模型为抽象类不会被创建abstract = True# 定义子类, 子类中包含父类中的所有属性以及自身所定义的属性
class Book(Base):name = models.CharField(max_length=32)class Author(Base):name = models.CharField(max_length=32)
多表继承
对于多表继承其父类也是一个 Django 模型,并且父类会创建一个数据表,多表继承是 Djnago 中一种隐式的一对一的关系:
# 父类
class Place(models.Model):name = models.CharField(max_length=50)address = models.CharField(max_length=80)
# 子类
class Restaurant(Place):serves_hot_dogs = models.BooleanField()serves_pizza = models.BooleanField()
这里 Restaurant 和 Place 是一对一的关系,当我们在执行 django 生成迁移文件命令时可以看到他们之间的关系。
注意⚠️:使用多表继承时父类子类必须是使用 django 迁移生成的表,否则无法正常使用表模型
proxy model(代理model)
使用代理模式的模型表不会被创建,其实都是指向同一个模型。
from django.db import modelsclass Person(models.Model):id = models.BigAutoField(primary_key=True)name = models.CharField(max_length=32)class OrderPerson(Person):class Meta:ordering = ['id']proxy = True
这里的 OrderPerson 并不会被创建,当我们在修改 OrderPerson 中的数据时对应的 Person 中的数据也会被修改。
注意⚠️:proxy model 不能继承抽象类,这是因为代理 model 是操作链接数据库的也不能多重继承,如果你使用了多重继承 proxy model 就不知道去找那个父亲类。
Django. model 中 related_name 使用
假设我们有如下两个模型 Book、Author
class Author(models.Model):id = models.BigAutiField(primary_key=True)name = models.CharField(max_length=32)class Book(models.Models):name = models.CharField(max_lenght=32)first_author = models.ForeignKey(Author, no_delete=models.CASCADE)secend_author = models.ForeignKey(Author, no_delete=models.CASCADE)
如上模型定义我们的书籍可能有多个作者,first_author secend_author 都关联 Author 这张表,如果我们运行该代码会被错。
原因:指向一个模型的两个外键反向关联名称产生冲突,django 默认情况下对每个主表的对象都有一个外键属性,可以通过它查询到所有关于子表的信息,这个属性的名字默认就是子表的名称小写加上_set,而 first_author 和 secend_author 该属性默认都是 book_set,导致冲突,解决办法:我们可以通过定义 related_name 来手动定义该属性,正确代码如下:
class Author(models.Model):id = models.BigAutiField(primary_key=True)name = models.CharField(max_length=32)class Book(models.Models):name = models.CharField(max_lenght=32)first_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='first_author')secend_author = models.ForeignKey(Author, no_delete=models.CASCADE, related_name='secend_author')