0

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 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.

Antigluk
  • 1,176
  • 2
  • 11
  • 30
  • 1
    See this: https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance – ypercubeᵀᴹ Sep 04 '11 at 20:50
  • 1
    And this answer for defining a super-type/subtype relationship in SQL: http://stackoverflow.com/questions/1722741/defining-a-one-to-one-relationship-in-sql-server/1723519#1723519 – ypercubeᵀᴹ Sep 04 '11 at 21:03

2 Answers2

1

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.

Luke Sneeringer
  • 9,270
  • 2
  • 35
  • 32
0

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

ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235
  • I think http://stackoverflow.com/questions/7301981/extra-info-for-model-with-several-types/7313375#7313375 do the same, but in more native way. – Antigluk Sep 07 '11 at 12:12