3

パラメータと呼ばれる抽象オブジェクトがあります。パラメータにはいくつかの異なるタイプがあります。例 - 数値パラメータ、定数パラメータ、MultiValue パラメータなど。各パラメータは、さまざまなタイプの多くのパラメータに関連付けることができ、その逆も可能です。

モデルの継承に関する 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 とモデルの継承を使用してこの目標を達成する方法はありますか?

ベース パラメーター モデルがそれ自体と多対多の関係を持つ独自のテーブルであり、サブ テーブルがバインドされていない 1 対 1 の関係で接続されている場合、これはデータベースに関する適切な解決策になる可能性があります。

4

3 に答える 3

1

マルチテーブル継承があなたの問題を解決すると思います。それを使用するには、サブクラス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
于 2013-10-02T17:43:37.627 に答える
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)
于 2013-10-02T18:02:29.133 に答える