我有一个名为parameter的抽象对象。参数可以是几种不同的类型。例如 - 数字参数,常量参数,MultiValue参数等。 每个参数都可以与不同类型的许多参数相关,反之亦然。
在Model inheritance审核了Django的文档后,我决定我需要的是一个简单的abstract base class。稍后可以在文档中找到基类的多对多关系的示例。
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和模型继承来实现这个目标?
如果基本参数模型是一个独立的表,其自身与多对多关系,并且子表与一对一关系解除关联,这可能是数据库方面的一个很好的解决方案。
答案 0 :(得分:1)
我认为multi-table inheritance会解决您的问题。要使用它,只需从abstract = True
子类中删除ParameterBase.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
答案 1 :(得分: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)
答案 2 :(得分:0)
如果您在抽象父类中使用 ManyToMany 字段,则应提供唯一的 related_name 作为stated in the docs。 。就您而言,这应该可以:
m2m = models.ManyToManyField('self',related_name='%(app_label)s_%(class)s_m2m')