python - Django:如何在 Django 中实现类的层次结构?

标签 python django abstract-class

我完全了解 MVC 框架以及 Django 如何实现模型和 View 。我想知道如何实现自定义层次结构类,然后在 Django 中使用它们。例如:

有一个抽象类Employee,然后是子类; 永久员工实习生等。公司可以雇用和解雇员工。

最佳答案

Django 中的模型继承的工作方式与 Python 中普通类继承的工作方式几乎相同,但仍应遵循页面开头的基础知识。这意味着基类应该是 django.db.models.Model 的子类。

您必须做出的唯一决定是您是否希望父模型本身成为模型(具有自己的数据库表),或者父模型是否只是仅通过子模型可见的公共(public)信息的持有者模型。

Django 中可能存在三种继承方式。

1)

通常,您只想使用父类来保存您不想为每个子模型键入的信息。这个类永远不会单独使用,因此抽象基类就是您所追求的。

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

编辑:

Abstract base classes

当您想要将一些公共(public)信息放入许多其他模型中时,抽象基类非常有用。您编写基类并将 abstract=True 放入 Meta 类中。该模型将不会用于创建任何数据库表。相反,当它用作其他模型的基类时,它的字段将添加到子类的字段中。抽象基类中的字段与子类中的字段同名是错误的(Django 将引发异常)。

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

Student 模型将具有三个字段:nameagehome_group。 CommonInfo 模型不能用作普通的 Django 模型,因为它是一个抽象基类。它不生成数据库表,也没有管理器,无法实例化或直接保存。

对于许多用途来说,这种类型的模型继承正是您想要的。它提供了一种在 Python 级别分解公共(public)信息的方法,同时仍然在数据库级别为每个子模型创建一个数据库表。

2)

如果您要对现有模型进行子类化(可能完全来自另一个应用程序)并希望每个模型都有自己的数据库表,那么多表继承就是正确的选择。

from django.db import models

class CommonInfo(models.Model):
    # ...
    class Meta:
        abstract = True
        ordering = ['name']

class Student(CommonInfo):
    # ...
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'

3)

最后,如果您只想修改模型的 Python 级别行为,而不以任何方式更改模型字段,则可以使用代理模型。

from django.db import models

class Base(models.Model):
    m2m = models.ManyToManyField(
        OtherModel,
        related_name="%(app_label)s_%(class)s_related",
        related_query_name="%(app_label)s_%(class)ss",
    )

    class Meta:
        abstract = True

class ChildA(Base):
    pass

class ChildB(Base):
    pass

与另一个应用程序rare/models.py一起:

from common.models import Base

class ChildB(Base):
    pass

有关更多信息,您可能需要继续阅读文档 here .

<小时/>

有一个维护良好的项目,名为 django-mptt ,使用 Django 模型实现修改的预序树遍历并使用模型实例树。

关于python - Django:如何在 Django 中实现类的层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42049596/

相关文章:

python - Python 中字符串的时间复杂度

javascript - django 模板循环调用 javascript 函数

c++ - 抽象类指针参数的默认值

python - 在 Python 中读取位于 S3 子文件夹下的文件的内容

python 如何在同一个文件中动态创建带有名称的类

python - 如果数据框列中的空值已存在于另一行中,则用相同的值填充该空值

Django 。基于类的 View 的一个很好的教程

django - 验证 JSON 数据

C# 抽象类继承

java - Java 中的抽象静态工厂方法 [getInstance()]?