15

私は現在、オブジェクトの種類に応じてさまざまな特性を持つことができる 1 つのモデルを含む Django のモデルに取り組んでいます。では、哺乳動物というモデルがあるとしましょう。これは、象またはイルカのいずれかになります (それぞれ独自の特性 "tusk_length" と "flipper_length" を持ちます)。

基本的な OOP の原則は「ポリモーフィズム」を叫んでおり、私は同意する傾向があります。しかし、私は Django を初めて使用するので、Django でこれを行うのが最善の方法であるかどうかを最初に知りたいと思います。私は多くの例を聞いており、何人かの人々は特異な巨大モデルを好みます

ここで説明されているように、既に GenericForeignKeys を使用してみました: Django の GenericForeignKey をモデルのリストに制限するにはどうすればよいですか? . このソリューションは見事に機能しますが、フィルター処理ができないことと、関係が一方通行であることは気に入りません。つまり、哺乳類オブジェクトからイルカを取得できますが、イルカから哺乳類オブジェクトを取得することはできません。

そして、ここに私の2つの選択肢があります:

選択肢 A:

from django.db import models
class Mammal(models.Model):
    hair_length = models.IntegerField()
    tusk_length = models.IntegerField()
    flipper_length = models.IntegerField()
    animal_type = models.CharField(max_length = 15, choices = ["Elephant", "Dolphin"]

選択肢 B:

from django.db import models
class Mammal(models.Model):
    hair_length = models.IntegerField()

class Elephant(Mammal):
    tusk_length = models.IntegerField()

class Dolphin(Mammal):
    flipper_length = models.IntegerField()

私が理解している選択肢 B には、すべての Elephants または Dolphins を照会して一覧表示するときに、より優れたコードが得られるという利点があります。ただし、哺乳類のリストからすべての象を取得するのは簡単ではないことに気付きました (これに対するクエリはありますか?)。クラスに animal_type を設定せずに、デフォルトはクラスに依存します。

これは、ポリモーフィズムで見られる別の問題につながります。これは、上記の例や私のアプリケーションでは発生しませんが、Dolphin オブジェクトを完全に削除せずに Dolphin オブジェクトを Elephant に編集するのは難しいということは言及する価値があります。

全体として、一般的な好みや、ポリモーフィズムを使用すべきではない大きな理由はありますか?

4

2 に答える 2

10

一般的にデータベース設計に関して、継承を避けることをお勧めします。アクセスと更新の両方が複雑になります。

Django で、基本モデルに抽象クラスを使用してみてください。つまり、db テーブルは作成されません。そのフィールド/列は、子モデルで自動作成されます。利点は、Django/Python コードでのコードの再利用と、データベースでのシンプルでフラットな設計です。ペナルティは、子モデルの混合コレクションを管理/クエリするのにより多くの作業が必要になることです。

ここで例を参照してください: Django パターン: モデルの継承

または、「哺乳類」の概念を「哺乳類の形質」に変更することもできます。そして、それぞれの特定の哺乳類クラス内に MammalTraits オブジェクトを含めます。コードでは、それがコンポジション (has-a) です。データベースでは、それは外部キーとして表現されます。

于 2013-05-01T05:29:42.873 に答える
2

通常は空の列がたくさんある大きなテーブルを使用することになりました。私たちの理由は、(この場合) Mammal テーブルだけがクエリの対象であり、「イルカ」または「ゾウ」が存在するかどうかを手動で確認する以外に、特定の種類の哺乳類で除外する (直感的な) 方法がなかったからです。 " オブジェクトであり、そうでない場合はエラーがスローされました。間違いなく象であるクエリから返されたオブジェクトの型を探しても、「哺乳動物」が返されました。私たちのデータ担当者の 1 人が定期的に行っている、純粋な SQL の記述に Pythonic の回避策を拡張するのは難しいでしょう。

于 2013-05-06T21:47:01.913 に答える