Django抽象模型真的有用吗?

3

我最近在一篇与Django相关的博客文章中看到了这个!

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

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


2
通常这样做是为了继承模型,从而避免重复代码。 - undefined
参考:https://docs.djangoproject.com/en/3.2/topics/db/models/#abstract-base-classes - undefined
3个回答

4
一个抽象模型被用来减少代码量,并在可重用的组件中实现公共逻辑。
例如,如果您有很多模型需要为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>

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


2

来自文档

抽象基类在您想要将一些共同信息放入其他多个模型中时非常有用。您编写基类并在Meta类中放置abstract=True。然后,此模型将不用于创建任何数据库表。相反,当它用作其他模型的基类时,其字段将添加到子类的字段中。

个人认为使用抽象模型的许多优点之一是它们允许软件扩展并根据SOLID原则禁止修改。


1
数据库表不是从具有"abstract=True"的类创建的,子类无法继承没有"abstract=True"的父类的字段。
例如,"学生"类扩展了"人员"类,该类具有"id"(隐藏),"姓名"和"年龄"字段,如下所示:
# "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

然后,分别从“Person”和“Student”类创建“myapp_person”和“myapp_student”表,并且由于“Student”类没有继承“Person”类的3个字段,“myapp_student”表中没有这些字段,而是有“person_ptr_id”,如下所示:

enter image description here

现在,在"Person"类中添加"abstract = True",如下所示:
# "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 # Here

class Student(Person):
   pass

然后,运行以下命令:

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

然后,只有从“Student”类创建了“myapp_student”表,并且因为“Student”类继承了“Person”类的3个字段,“myapp_student”表如下所示:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接