1 つの方法は、すべての共通プロパティを含む「メイン」テーブルを作成し、オブジェクトのタイプごとに個別のテーブルを作成することです。これは Django で行うのが非常に簡単で、モデル定義は「クリーン」に見えます。詳細については、複数テーブルの継承を参照してください。
あなたの状況のモデル例:
# Hold common fields/properties
class Item(models.Model):
type = ...
price = ...
weight = ...
width = ...
height = ...
...
# Below are example classes which will inherit all properties from Item
class CPU(Item):
frequency = ...
core_count = ...
socket = ...
class Smartphone(Item):
os = ...
display_size = ...
cpu = models.ForeignKey(CPU, ...) # Example linking between items.
各「具体的な」項目は、共通テーブルと「具体的な」テーブルの 2 つのデータベース行で構成されることに注意してください。2 つのテーブルは、「具体的な」テーブルの 1 対 1 のフィールドで結合されます (Django はこのフィールドを追加しますが、必要に応じて再定義できます)。
データベースからアイテムを取得するメソッドの例:
# Get all "base" items without touching type tables
Item.objects.all()
# Get all items along with their child properties. This is rather ugly and expensive.
Item.objects.select_related('cpu', 'smarthphone', ...).all()
# Gets smartphones, uses a join to retrieve data from two tables.
# I don't remeber if the `select_related` is required here.
Smartphone.objects.select_related('item').all()
# When type of the item is only know at runtime, you can query like this (requires additional table column for storing type):
Item.objects.filter(type='smartphone')
# Or alternatively finding out which type class you want.
利点:
- クラス定義はすっきりとシンプルに見えます。
- 最適なデータベース構造に非常に近い。
- 1 つのデータベース クエリで、さまざまな種類のアイテムを取得できます。
短所:
- 完全なデータを含むオブジェクトを取得するときの過剰な結合。