ここで疑問があります...
3 つのクラスがあるとします。
class CarSpec(models.Model):
x = models.IntegerField(default=20)
y = models.CharField(max_length=100, blank=True)
z = models.CharField(max_length=50, blank=True)
chassis = models.ForeignKey(Chassis, unique=True, limit_choices_to={'type':'A'})
car_brand = models.CharField(max_length=100, blank=True)
car_model = models.CharField(max_length=50, blank=True)
number_of_doors = models.IntegerField(default=2)
class MotoSpec(models.Model):
x = models.IntegerField(default=20)
y = models.CharField(max_length=100, blank=True)
z = models.CharField(max_length=50, blank=True)
chassis = models.ForeignKey(Chassis, unique=True, limit_choices_to={'type':'C'})
motor_brand = models.CharField(max_length=100, blank=True)
motor_model = models.CharField(max_length=50, blank=True)
powered_weels = models.IntegerField(default=1)
class Chassis(models.Model):
name = models.CharField(max_length=50, blank=False)
type = models.CharField(max_length=2, choices = GAME_TYPES, default="A")
GAME_TYPES = (('A', 'Car'),('B', 'Truck'),('C', 'Motorcycle'))
私はこの 3 つのクラスで作業していましたが、私のアプリでは、それぞれの状況にいくつかのビジネス ルールを適用するために、シャーシの種類を常に確認する必要がありました...これは正しいアプローチではないと思ったので、計画しました.これ:
class Spec(models.Model):
x = models.IntegerField(default=20)
y = models.CharField(max_length=100, blank=True)
z = models.CharField(max_length=50, blank=True)
class Meta:
abstract = True
2 つのサブクラスがあります。
class CarSpec(Spec):
chassis = models.ForeignKey(Chassis, unique=True, limit_choices_to={'type':'A'})
car_brand = models.CharField(max_length=100, blank=True)
car_model = models.CharField(max_length=50, blank=True)
number_of_doors = models.IntegerField(default=2)
class MotoSpec(Spec):
chassis = models.ForeignKey(Chassis, unique=True, limit_choices_to={'type':'C'})
motor_brand = models.CharField(max_length=100, blank=True)
motor_model = models.CharField(max_length=50, blank=True)
powered_weels = models.IntegerField(default=1)
class Chassis(models.Model):
name = models.CharField(max_length=50, blank=False)
type = models.CharField(max_length=2, choices = GAME_TYPES, default="A")
GAME_TYPES = (('A', 'Car'),('B', 'Truck'),('C', 'Motorcycle'))
わかりました、ここまではすべて大丈夫です。以前のクラスで動作していたアプリで何も変更されず、すべてのオブジェクトが期待どおりにデータベースに保持されていました..
しかし、私の問題は残ります..私は引き続き CarSpec と MotoSpec をインスタンス化し、Spec ではありません...しかし... クラスを拡張する代わりに常に Spec を使用したいのですが...そのためにはどうすればよいですか?その (または他の) メソッドから CarSpec または MotoSpec を取得するために、Chassis を彼のinitメソッドに渡す Spec オブジェクトをインスタンス化することができます..
EDITED-IMPORTANT:2つのスペックのそれぞれに特定のフィールドがあるため、MotoSpecのpowered_weels属性とCarSpecのnumber_of_doors属性を追加しました
EDITED-YET AGAIN : 私の見解では、仕様をいじるたびに型検証を行うことを避け、関連するクラスの 1 つに任せたいと考えていました。再開すると、新しい仕様オブジェクトを追加できるようになり、ビューの変更について心配する必要がなくなります.仕様に関連するオブジェクトのみ..
# CarSpec
if game_type == "A":
stuff = CarSpec.restore_state(request, game_session)
# MotoSpec
elif game_type == "C":
stuff = MotoSpec.restore_state(request, game_session)
EDITED : Spec クラスに restore_state を追加しましたが、循環インポートに関連するいくつかの問題を見つけたと思います..OMG..これは私を殺しています。私は.NETのバックグラウンドを持っています.Pythonは、この種のものでは簡単ではありません:S