I have some doubts here...
Imagine that I have 3 classes:
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'))
I was working with this 3 classes, but in my apps I would have to check the chassis type all the time in order to apply some business rules to each situation... I thought this would not be the correct approach.. so I planned this:
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
and have two Subclasses:
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'))
Ok, until here all ok, changed nothing in my apps that worked with previous classes and all objects were being persisted in the database quite nicely as expected..
But, my problem remains.. Because I continue to instantiate CarSpec and MotoSpec and not Spec... but... I want to use Spec all the time instead of the extending classes... being so, what can I do to be able to instantiate a Spec object passing a Chassis to his init method in order to get a CarSpec or a MotoSpec from that (or other) method..
EDITED-IMPORTANT: I've added powered_weels attribute for MotoSpec and number_of_doors for CarSpec because I have some specific fields for each of the two Specs
EDITED-YET AGAIN: In my views I wanted to avoid doing a type verification every time I mess around with Specs and leave that to one of the classes involved. Resuming, I want to be able to add a new Spec Object and not have to worry about changing my views.. only the objects related to 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)
EDITED: I've added a restore_state on my Spec class, but then I think I find some problems related to circular imports.. OMG.. this is killing me. I have a .NET background, and python is not getting easy on me in this kinds of stuff :S