Extra info for model with several types
I want to do some unusual in Django orm.
I have the model Car
. How can I extend it with additional information, separated by type, storing in another model?
For example, for entry of Car
"My Truck", which type is truck
, i want to extend it with TruckInfo
model.
Another entry "My Bus" i want to extend with BusInfo
model.
In other words, i want to make开发者_StackOverflow社区 a floating relationship.
It could be implemented by adding to Car
column with type, and performing SELECT
twice: 1) for selecting cars, 2) for selecting extra info using Car.Type field. But it is terrible solution. I want to make it in a single query.
Maybe you know solution in pure SQL, it will be useful too. Thx.
It's going to be pretty hard to give you a definitive answer without asking a lot more about your particular needs. However, there's nothing in Django's ORM that prevents you from doing this.
Here's a way to do it -- note that I don't by any means claim that it's the only way, and I might recommend something else if given more clarification on your goals:
class Automobile(models.Model):
[...]
type = models.ChoiceField(choices=(
('car', 'Car'),
('truck', 'Truck'),
('bus', 'Bus'),
))
@property
def detail(self):
return getattr(self, self.type)
class Car(Automobile):
[...]
class Truck(Automobile):
[...]
class Bus(Automobile):
[...]
Be sure that, if you go this route, you'll want to read the documentation on multi-table inheritance: https://docs.djangoproject.com/en/1.3/topics/db/models/#multi-table-inheritance
You also may or may not want the top-level model to be an actual table (see the text just above in the link I gave you for a discussion of abstract models). I can't tell you which to use -- it's specific to what you're trying to do.
You'll also probably want some custom signals that enforce data accuracy -- for instance, to make sure you don't save a Bus record for an automobile of type Truck.
I guess you can also do this:
class Automobile(models.Model):
# ...
class Truck(models.Model):
automobile = models.OneToOneField(Automobile, primary_key=True)
# ...
class Bus(models.Model):
automobile = models.OneToOneField(Automobile, primary_key=True)
# ...
Some explanations here: OneToOneField reference
and an example with more details can be found here: One-to-one relationship example
精彩评论