基于两个抽象类的Django模型

5lhxktic  于 2022-11-18  发布在  Go
关注(0)|答案(1)|浏览(146)

我有一个概念性的问题,但有实际意义。
在Django 4.1.x应用中,我有一个owner类,它可以是personorganization,但不能同时是personorganization
这两个类不需要在数据库中注册,只有owner必须:

from django.db import models

class Person(models.Model):
    first_name = models.CharField(
        max_length=256,
        verbose_name=_("First name"),
        null=False,
    )
    # other person attributes, e.g.:
    surname = models.CharField(
        max_length=256,
        verbose_name=_("Surname"),
        null=False,
    )
    street = models.CharField(
        max_length=256,
        verbose_name=_("Street"),
        null=False,
    )
    country = models.CharField(
        max_length=256,
        verbose_name=_("Country"),
        null=False,
    )

    class Meta:
        abstract = True
    
    def __str__(self):
        return self.first_name

class Organization(models.Model):
    full_name = models.CharField(
        max_length=256,
        verbose_name=_("Full name"),
        null=False,
    )
    # other organization attributes, e.g.:
    register_identifier = models.CharField(
        max_length=64,
        verbose_name=_("Register identifier"),
        null=False,
    )
    street = models.CharField(
        max_length=256,
        verbose_name=_("Street"),
        null=False,
    )
    country = models.CharField(
        max_length=256,
        verbose_name=_("Country"),
        null=False,
    )
    
    class Meta:
        abstract = True
    
    def __str__(self):
        return self.full_name

无论owner示例是什么,它都必须具有name属性:
如果是个人,则所有者的名称必须为first_name;如果是组织,则所有者的名称必须为full_name
此外,如果owner对象是Person的实体:我只想公开Person的其他属性,如果ownerOrganization的示例,也是一样。
我当然错过了这里的一些概念/也许我没有在正确的方向上寻找,但如何构建基于“条件或参数化继承”类型的owner模型,让我们说?
请注意,Person类也用于构建其他对象,例如整个应用程序中的designerpainterOrganization也是如此,它作为不同类型组织的基础。因此,它们的abstract = True

编辑

正如SamSparx在下面的注解中所建议的,我已经尝试使用吸引人的“代理”概念。为此,我需要从PersonOrganization类中删除abstract = True标志,并在Owner类中设置proxy = True。但是,当尝试makemigrations时,它说:
第一次
这是预期的,正如医生所说:基底类别限制
代理模型只能继承一个非抽象模型类。不能继承多个非抽象模型,因为代理模型不提供不同数据库表中的行之间的任何连接。代理模型可以继承任意数量的抽象模型类。代理模型也可以从共享公共非抽象父类的任意数量的代理模型继承。
来源:https://docs.djangoproject.com/en/4.1/topics/db/models/#base-class-restrictions
所以现在也没什么用。

68bkxrlz

68bkxrlz1#

有几种可能的方法,但它们都有折衷。这在很大程度上取决于你的类都使用同一个表的重要性。作为经验法则,如果一个非抽象模型需要新的字段,它就需要一个新的表。
抽象类:
这两个类作为原型很有用,但是你不能把它们组合起来,这样就只有一个抽象类“active”。如果Org和Person都是用来创建Owner的抽象类,那么Owner将拥有这两个类中的所有字段。
任何非抽象类都需要自己的表,例如,Owner的子类或其他具有Person抽象的类。
代理类:
这基本上是您只使用一个表的选择。使用这种方法,您可以为您的类创建单独的子类,并且它的所有子类都使用同一个表,每个类都有不同的方法和属性。但是,它们必须共享相同的字段。如果只是偶尔子类需要新字段,则可以将它们添加到基类中,而不需要太多的开销。并通过相应的代理类的方法处理或忽略。

相关问题