继承使您可以重用代码并创建更清晰的数据模型。但 Django 提供了不止一种继承方式,因此请确保您了解其中的差异。
模型继承是 Django ORM 的一项功能,允许开发人员在数据库模型之间创建层次关系。它通过利用面向对象编程的原理来实现代码重用、可扩展性和更清晰的代码库。
无论您是构建复杂的 Web 应用程序还是处理较小的项目,模型继承都可以带来显着的好处,例如减少冗余并确保行为一致。
Django 中模型继承的类型Django 支持三种类型的模型继承:
抽象基类。
多表继承。
代理模型。
每种类型的模型继承都有其优点,您可以将它们用于特定目的。
抽象基类抽象基类提供了一种定义多个模型可以继承的公共字段和方法的方法。例如,如果您有两个模型共享相似的字段,则可以使用抽象基类来定义相似的字段。看一下这个例子:
class Customer(models.Model): name = models.CharField(max_length=50) email = models.EmailField() customer_id = models.IntegerField() Seller(models.Model): name = models.CharField(max_length=50) email = models.EmailField() seller_id = models.IntegerField()
上面的代码片段定义了两个 Django 模型:Customer 和 Seller。这些模型共享两个公共字段,即姓名和电子邮件。为了防止这种冗余,您可以创建一个单独的模型来保存 Customer 和 Seller 模型中的公共字段并使其抽象。
class UserInfo(models.Model): name = models.CharField(max_length=50) email = models.EmailField() class Meta: abstract = True
上面的代码片段定义了一个新模型并将abstract属性设置为True。这意味着模型将是抽象的,Django 不会在数据库中创建表。
您可以像这样重写 Customer 和 Seller 模型:
class Customer(UserInfo): customer_id = models.IntegerField() Seller(UserInfo): seller_id = models.IntegerField()
在上面的代码片段中,Customer 和 Sellers 模型继承自 UserInfo 模型而不是 models.Model。
您可以通过在 admin.py 文件中注册模型来在管理面板中查看模型,如下所示:
from .models import Customer, Selleradmin.site.register(Customer)admin.site.register(Seller)
通过在命令行上运行以下命令来迁移模式并启动开发服务器:
python manage.py makemigrations \ && python manage.py migrate \ && python manage.py runserver
导航到您的管理站点并使用您的超级用户详细信息登录。您应该看到每个模型的所有三个字段。
在此示例中,Django 为 Customer 和 Seller 模型创建了一个表。您可以看到 UserInfo 模型没有表,因为它是抽象的。
多表继承当父模型也需要与子模型一起作为数据库中的表存在时,您可以使用多表继承。
与抽象基类继承(其中父模型不是数据库中的表)不同,多表继承为父模型创建一个表。
在多表继承中,子模型继承父模型的所有字段和方法,并添加其特定字段。外键有助于建立父模型和子模型之间的模型关系。
下面是多表继承的示例:
class Person(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) def get_name(self): return f"{self.first_name} {self.last_name}" class Meta: abstract = Trueclass Employee(Person): employee_id = models.CharField(max_length=20) department = models.CharField(max_length=100) salary = models.FloatField() dob = models.DateField()class Manager(Employee): title = models.CharField(max_length=100)
此代码片段定义了三个模型。第一个模型称为 Person,是抽象的。它仅定义一个人的名字和姓氏。
第二个模型称为 Employee,继承了 Person 的字段,但定义了其他字段。 Employee 模型不是抽象的,因此它将在数据库中拥有自己的表。
最终模型称为 Manager,继承了 Employee 模型的字段并添加了一个称为 title 的字段。
Employee 和 Manager 模型之间的关系称为多表继承。迁移您的模型,在 admin.py 中注册它们,启动服务器,然后导航到管理面板。您应该看到 Django 创建的两个表。
当您尝试添加新经理时,您会注意到它具有 Employee 模型中的所有字段以及它自己的自定义字段。
代理模型代理模型可帮助您创建从现有模型扩展的新模型,而无需创建新的数据库表。在这种模型继承中,代理模型和原始模型将共享同一个表。使用代理模型,您可以执行创建自定义模型和更改默认管理器等操作。
您可以通过在 Meta 类中添加 proxy=True 来创建代理模型。这是一个例子:
class ProxyModel(BaseModel): class Meta: proxy = True
当存在基本模型并且需要创建具有附加功能的专用版本时,代理模型的典型用法是合适的。这是一个基本示例:
class Post(models.Model): title = models.CharField(max_length=30) author = models.CharField(max_length=30) def __str__(self): return self.titleclass ProxyPost(Post): class Meta: proxy = True
此代码片段定义了两个模型:Post 和 MyPost。 Post 模型定义了标题和作者两个字段。 ProxyPost模型继承自Post模型。
迁移上述模型并将新帖子添加到为 Post 模型创建的表中。
添加帖子后,打开代理帖子表。您应该在其中找到添加到“帖子”表中的帖子。
您对代理帖子表中的帖子所做的更改将影响帖子表中相应的帖子,反之亦然。这证明他们确实是同桌的。
您可以修改代理模型的 str() 方法:
class ProxyPost(Post): class Meta: proxy = True ordering = ["title"] def __str__(self): return self.author
通过此修改,ProxyPost 的字符串表示形式将是其作者,而不是标题。代理模型的排序也将按标题而不是默认 ID 字段。
使用代理模型时,您应该记住,您无法将自定义字段添加到代理模型中。代理模型的主要用例是当您希望一个模型支持多种行为时。
代理模型可帮助您更改现有模型的行为,而无需修改其字段或基础数据库表结构。
使用模型继承来实现代码可重用性和组织结构通过利用模型继承的不同技术,您可以轻松地为您的项目创建可重用且有组织的代码。
模型继承避免了冗余代码并增强了代码的可维护性和可扩展性。它还使您可以轻松浏览代码,从而促进开发团队之间的高效协作。
除了模型继承之外,Django 还提供模板继承,这是管理和组织项目模板的好方法。