Django 抽象模型真的那么有用吗?

Are django abstract models really that useful?

我最近在一篇与 django 相关的博客中看到了这个 post!

class Client(models.Model):
   name = models.CharField(max_length=255, required=True)
   # .. other fields
   class Meta:
     abstract = True

阅读文档后,我不明白“abstract = True”的目的是什么。 任何帮助都会有用。谢谢!

抽象模型用于减少代码量,并在可重用组件中实现通用逻辑。

例如,如果你有很多模型,你想为 created_atupdated_at 定义两个时间戳,那么我们可以从一个简单的抽象模型开始:

class <b>UpdatedCreated</b>(models.Model):
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        <b>abstract = True</b>

如果我们现在有三个模型,我们想在其中包含这些时间戳,我们可以使用:

class Foo(<b>UpdatedCreated</b>):
    other=models.CharField()


class Bar(<b>UpdatedCreated</b>):
    another=models.CharField()


class Qux(<b>UpdatedCreated</b>):
    an_another=models.CharField()

现在这三个模型都有一个 created_atupdated_at 字段。如果我们在 UpdatedCreated 上定义方法,那么模型将 继承 这个。例如,我们可以创建一个字段来指定该项目是否仍然“有效”:

from django.utils.timezone import now

class UpdatedCreated(models.Model):
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    @property
    def <b>alive</b>(self):
        return (now() - updated_at).days < 7

    class Meta:
        <b>abstract = True</b>

因此,这是一种通过相同的可重用组件轻松扩展模型的方法。

来自docs

Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

就我个人而言,我发现使用抽象模型的众多优势之一是它们允许软件扩展并根据 SOLID 原则禁止修改。

数据库 table 不是从具有 "abstract=True" 的 class 创建的,子 class 不能继承来自父 class 的字段没有 "abstract=True".

例如,“学生”class 扩展了 “人”class “id”(隐藏)、“name”和“age”字段如下所示:

# "myapp/models.py"

from django.db import models

class Person(models.Model):
   name = models.CharField(max_length=100)
   age = models.IntegerField()

class Student(Person):
   pass

然后,运行下面这个命令:

python manage.py makemigrations && python manage.py migrate

然后,"myapp_person" 和 "myapp_student" tables"Person" 和“学生”classes 分别因为 “学生”class 不继承 3 个字段 来自 "Person" class, "myapp_student" table 没有它们,而是它有 "person_ptr_id",如下所示:

现在,将 "abstract = True" 添加到 "Person" class,如下所示:

# "myapp/models.py"

from django.db import models

class Person(models.Model):
   name = models.CharField(max_length=100)
   age = models.IntegerField()

   class Meta:
      abstract = True

class Student(Person):
   pass

然后,运行下面这个命令:

python manage.py makemigrations && python manage.py migrate

那么,只有"myapp_student" table是从"学生"class[=54=创建的] 并且因为 "Student" class"Person" class[= 继承了 3 个字段 54=], "myapp_student" table 如下所示: