【发布时间】:2013-02-07 15:55:14
【问题描述】:
我这里有些疑惑……
假设我有 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 个类,但在我的应用程序中,我必须一直检查 chassis 类型,以便将一些业务规则应用于每种情况...... 我认为这不是正确的方法.. 所以我计划了这个:
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
并且有两个子类:
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 而不是扩展类...这样,我能做什么为了能够实例化一个 Spec 对象,将 Chassis 传递给他的 init 方法,以便从该(或其他)方法获取 CarSpec 或 MotoSpec..
EDITED-IMPORTANT:我为 MotoSpec 添加了 powered_weels 属性,并为 CarSpec 添加了 number_of_doors 属性 因为我对两个 Specs 中的每一个都有一些特定的字段
再次编辑:在我看来,我希望避免每次在处理 Specs 时都进行类型验证,并将其留给所涉及的类之一。继续,我希望能够添加一个新的 Spec 对象,而不必担心更改我的视图.. 只有与 Specs 相关的对象..
# CarSpec
if game_type == "A":
stuff = CarSpec.restore_state(request, game_session)
# MotoSpec
elif game_type == "C":
stuff = MotoSpec.restore_state(request, game_session)
已编辑:我在我的 Spec 类中添加了一个 restore_state,但后来我想我发现了一些与循环导入相关的问题.. OMG.. 这让我很生气。我有 .NET 背景,python 在这些方面对我来说并不容易:S
【问题讨论】:
标签: python django class subclass abstract