开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜