python - Django:复合字段或嵌入式类(如 JPA)?

标签 python django django-models

假设您必须对多个类建模,这些类应该具有复合属性,例如尺寸(宽度高度)或电话号码(前缀编号扩展名)。

在 Java 中(使用 JPA 2)我会创建一个 Dimensions 类并用 @Embeddable 注释它。这会导致 Dimension 的 字段(例如 widthheight)被嵌入到声明类型为 Dimensions.

如何在避免代码重复的同时使用 Django 对这些进行建模?创建单独的 Dimensions 模型并使用 ForeignKey 字段引用它没有意义。而且这些类没有足够的共同点来证明模型继承的合理性。

最佳答案

我认为您可能过度考虑了继承。继承是并且实际上是复合模型的推荐方法。以下是如何在 Django 中正确使用模型继承的示例:

class PhoneModelBase(model.Model):
    phone = models.CharField(max_length=16)
    ...

    class Meta:
        abstract = True

class PhoneModel(PhoneModelBase):
    # phone is here without typing it
    # the only restriction is that you cannot redefine phone here
    # its a Django restriction, not Python restriction
    # phone = models.CharField(max_length=12) # <= This will raise exception
    pass

所以它所做的是创建一个模型 PhoneModelBase,但是这里的关键是它使用 class Metaabstract=True

这里有更多关于正在发生的事情的幕后故事以及对一些 Python 概念的一些解释。我假设您不知道它们,因为您在问题中提到了 Java。这些 Python 概念实际上是比较困惑的概念,所以我的解释可能不完整,甚至令人困惑,所以如果你不会遵循,请不要介意。您只需要知道使用 abstact = True。这是官方文档:https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes .

PhoneModelBase 中的

Meta 属性就是一个属性。它与类中的任何其他属性相同,除了它是一个类实例(请记住,在 Python 中,类和函数是一阶成员)。此外,Python 有一个名为 __metaclass__ 的东西,您可以将其添加到您的类中。 __metaclass__ 定义了一种构建类实例的方式。更多相关信息 here . Django 在创建模型类实例的过程中使用了这些。

所以要创建PhoneModelBase类,下面是一个大概的轮廓:

  • PhoneModelBase 类的实例(类本身,而不是类的实例 - PhoneModelBase())被创建时,__metaclass__ 由于继承而来自 model.Model 接管创建过程
  • __metaclass__ 中,Python 调用创建实际类实例的函数,并将您尝试创建的类的所有字段传递给它 - PhoneModelBase。这将包括 phoneMeta 和您定义的任何其他字段
  • 它看到 Meta 属性,然后开始分析它的属性。根据这些属性的值,Django 会改变模型的行为
  • 它看到 abstract 属性,然后更改它试图创建的类的逻辑 - PhoneModelBase 不将它存储在 db 中

然后是 PhoneModelBase,尽管它的定义看起来与常规模型非常相似,但它不是常规模型。它只是一个抽象类,旨在用作其他模型中的组合。

当其他模型继承自 PhoneModelBase 时,它们的 __metaclass__ 将从基础模型中复制属性,就像您手动键入这些属性一样。它不会是任何类似的外键。所有继承的属性都将成为模型的一部分,并将在同一个表中。

希望所有这些都有意义。如果不是,您只需记住将 Meta 类与 abstract = True 一起使用即可。

编辑

如评论中所建议的,您还可以从多个基类继承。因此,您可以拥有 PhoneModelBaseDimensionsModelBase,然后您可以从这两个(或更多)继承,所有基类的所有属性都将出现在您的模型。

关于python - Django:复合字段或嵌入式类(如 JPA)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12493568/

相关文章:

python - 如何修复 "plural forms could be dangerous"django 错误?

jquery - 在 django 应用程序中使用 jquery fullcalendar

Django unique_together 关于父属性的子类模型?

Django南: Re-run first migration

javascript - 元胞自动机在 Python 中运行,而不是在 Javascript 中运行

python - Python 中的 __str__ 方法

python - 向行添加条目以使其统一

python - Django "Unable to determine the file' s size“tempfile.TemporaryFile 错误

python - 如何阻止某些单词在 Django 表单中使用?

java - 通过套接字从java发送固定长度数组到python