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_at
和 updated_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_at
和 updated_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 如下所示:
我最近在一篇与 django 相关的博客中看到了这个 post!
class Client(models.Model):
name = models.CharField(max_length=255, required=True)
# .. other fields
class Meta:
abstract = True
阅读文档后,我不明白“abstract = True”的目的是什么。 任何帮助都会有用。谢谢!
抽象模型用于减少代码量,并在可重用组件中实现通用逻辑。
例如,如果你有很多模型,你想为 created_at
和 updated_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_at
和 updated_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 如下所示: