7

Person人に関するすべてのデータを格納するモデルがあります。ClientPerson を拡張するモデルもあります。モデルを拡張する別の拡張モデルOtherPersonがありPersonます。を指すクライアントを作成したいのですが、それを指すレコードもPerson作成します。基本的に、現在のビューに応じて、 1 つのオブジェクトをおよびとして表示したいと考えています。これは Django の ORM で可能ですか、またはこのシナリオを作成するために生のクエリを何らかの方法で作成する必要がありますか? 両方の子クラスが person_ptr_id フィールドで親の Person クラスを指すだけなので、データベース側からは可能であると確信しています。OtherPersonPersonPersonClientOtherPerson

簡単に言えば、 をClient(つまり を) 作成した場合、 のベースを使用してオブジェクトをPerson作成することもできますか? そうすれば、それらをOR として表示でき、保存するとそれぞれのフィールドに影響しますか?OtherPersonPersonClientClientOtherPersonPerson

「水平」ポリモーフィズム?

これが明確になる場合に備えて、私のモデルの縮小版です。

class Person(models.Model):
    """
        Any person in the system will have a standard set of details, fingerprint hit details, some clearances and items due, like TB Test.
    """
    first_name = models.CharField(db_index=True, max_length=64, null=True, blank=True, help_text="First Name.")
    middle_name = models.CharField(db_index=True, max_length=32, null=True, blank=True, help_text="Middle Name.")
    last_name = models.CharField(db_index=True, max_length=64, null=True, blank=True, help_text="Last Name.")
    alias = models.CharField(db_index=True, max_length=128, null=True, blank=True, help_text="Aliases.")
    .
    .
    <some person methods like getPrintName, getAge, etc.>

class Client(Person):
    date_of_first_contact = models.DateField(null=True, blank=True)
    .
    .
    <some client methods>


class OtherPerson(Person):
    active_date = models.DateField(null=True, blank=True)
    termination_date = models.DateField(null=True, blank=True)
    .
    .
    <some other person methods>
4

4 に答える 4

2

あなたがやっていることはあなたがやっているようには不可能です.Djangoには継承のための特定のルールがあります.

唯一可能なスキーマは次のとおりです。

class Parent(models.Model):
    class Meta:
        abstract = True # MUST BE !!! This results in no relation generated in your DB

    field0 = models.CharField(...
    ...

    # here you're allowed to put some functions and some fields here


class Child(models.Model):
    field1 = models.CharField(...
    ...

    # Anything you want, this model will create a relation in your database with field0, field1, ...


class GrandChild(models.Model):
    class Meta:
        proxy = True # MUST BE !!! This results in no relation generated in your DB

    # here you're not allowed to put DB fields, but you can override __init__ to change attributes of the fields: choices, default,... You also can add model methods.

これは、ほとんどの DBGS に DB 継承がないためです。したがって、親クラスにする必要がありますabstract

于 2013-08-08T16:03:19.653 に答える
1

サブクラス化では実際にそれを行うことはできません。をサブクラス化すると、オブジェクトPersonではなくサブクラスを作成することを暗黙的に Django に伝えます。Personを取り、Personそれを後でに変身させるのはPITAOtherPersonです。

おそらく、OneToOneField代わりに が必要です。Clientとの両方OtherPersonが のサブクラスである必要がありますmodels.Model:

class Client(models.Model):
    person = models.OneToOneField(Person, related_name="client")
    # ...

class OtherPerson(models.Model):
    person = models.OneToOneField(Person, related_name="other_person")
    # ...

次に、次のようなことができます。

pers = Person(...)
pers.save()
client = Client(person=pers, ...)
client.save()
other = OtherPerson(person=pers, ...)
other.save()

pers.other.termination_date = datetime.now()
pers.other.save()

詳細については、 https://docs.djangoproject.com/en/dev/topics/db/examples/one_to_one/を参照してください。

于 2013-08-08T16:07:13.870 に答える