3

我有一个称为参数的抽象对象。参数可以是几种不同的类型。例如 - 数字参数、常量参数、多值参数等。每个参数可以与许多不同类型的参数相关,反之亦然。

在查看了 Django 关于模型继承的文档后,我决定我需要一个简单的抽象基类。稍后可以在文档中找到来自基类的多对多关系的示例。

class ParameterBase(models.Model):
    id = models.AutoField(primary_key=True)    
    description = models.CharField(max_length=200)
    sort_order = models.DecimalField(null=False, max_digits=6, decimal_places=4)

    m2m = models.ManyToManyField('self',related_name='dependent_on')

    class Meta:
        abstract = True

class ParameterConstant(ParameterBase):
    value = models.DecimalField(null=False, blank=False, max_digits=20 , decimal_places=4)

class ParameterNumeric(ParameterBase):
    minimum = models.DecimalField(null=True, blank=True, max_digits=20 , decimal_places=4)    
    maximum = models.DecimalField(null=True, blank=True, max_digits=20 , decimal_places=4)

所以在同步之后我可以看到 django 创建了 4 个表 -

CREATE TABLE "calc_parameterconstant_m2m" (
    "id" serial NOT NULL PRIMARY KEY,
    "from_parameterconstant_id" integer NOT NULL,
    "to_parameterconstant_id" integer NOT NULL,
    UNIQUE ("from_parameterconstant_id", "to_parameterconstant_id")
)
;
CREATE TABLE "calc_parameterconstant" (
    "id" serial NOT NULL PRIMARY KEY,
    "description" varchar(200) NOT NULL,
    "sort_order" numeric(6, 4) NOT NULL,
    "value" numeric(20, 4) NOT NULL
)
;
ALTER TABLE "calc_parameterconstant_m2m" ADD CONSTRAINT "from_parameterconstant_id_refs_id_f893bb67" FOREIGN KEY ("from_parameterconstant_id") REFERENCES "calc_parameterconstant" ("id") DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE "calc_parameterconstant_m2m" ADD CONSTRAINT "to_parameterconstant_id_refs_id_f893bb67" FOREIGN KEY ("to_parameterconstant_id") REFERENCES "calc_parameterconstant" ("id") DEFERRABLE INITIALLY DEFERRED;

CREATE TABLE "calc_parameternumeric_m2m" (
    "id" serial NOT NULL PRIMARY KEY,
    "from_parameternumeric_id" integer NOT NULL,
    "to_parameternumeric_id" integer NOT NULL,
    UNIQUE ("from_parameternumeric_id", "to_parameternumeric_id")
)
;
CREATE TABLE "calc_parameternumeric" (
    "id" serial NOT NULL PRIMARY KEY,
    "description" varchar(200) NOT NULL,
    "sort_order" numeric(6, 4) NOT NULL,
    "minimum" numeric(20, 4),
    "maximum" numeric(20, 4)
)

现在,这显然不是我的意图——我希望能够将每种类型的参数也连接到其他类型的参数。有没有办法使用 Django ORM 和模型继承来实现这个目标?

如果基本参数模型是一个独立的表,并且与它自身具有多对多关系,并且子表与未绑定的一对一关系连接,那么这可能是数据库明智的一个很好的解决方案。

4

3 回答 3

1

解决此问题的一种方法是替换

m2m = models.ManyToManyField('self',related_name='dependent_on')

m2m = models.ManyToManyField('ParameterBase', related_name='dependent_on')

但是 Django 不会让您创建一个 m2m 字段,该字段指向尚未安装的模型或抽象模型。在这一点ParameterBase上,两者兼而有之。

我会这样做

class Parameter(models.Model):
    id = models.AutoField(primary_key=True)    
    description = models.CharField(max_length=200)
    sort_order = models.DecimalField(null=False, max_digits=6, decimal_places=4)

class ParameterType(models.Model):
    parameter = models.ForeignKey(Parameter)
    related_parameters = models.ManyToManyField(Parameter,related_name='dependent_on')

    class Meta:
        abstract = True

class ParameterConstant(ParameterType):
    value = models.DecimalField(null=False, blank=False, max_digits=20 , decimal_places=4)

class ParameterNumeric(ParameterType):
    minimum = models.DecimalField(null=True, blank=True, max_digits=20 , decimal_places=4)    
    maximum = models.DecimalField(null=True, blank=True, max_digits=20 , decimal_places=4)
于 2013-10-02T18:02:29.133 回答
1

我认为多表继承将解决您的问题。要使用它,只需abstract = TrueParameterBase.Meta子类中删除(或完全删除该子类)。

使用多表继承时,要访问特定子类的属性,Django 必须知道您正在处理该子类。

例如,这将失败:

p = ParameterBase.objects.get(...)  # get a ParameterBase that is a ParameterConstant
print p.value

相反,您必须这样做:

p = ParameterConstant.objects.get(...)
print p.value

或这个:

p = ParameterBase.objects.get(...)  # get a ParameterBase that is a ParameterConstant
print p.paramaterconstant.value
于 2013-10-02T17:43:37.627 回答
0

如果您在抽象父类中使用ManyToMany字段,则应提供文档中所述的唯一相关名称...在您的情况下,这应该没问题:

m2m = models.ManyToManyField('self',related_name='%(app_label)s_%(class)s_m2m')

于 2018-12-07T22:50:22.443 回答