[Django]-Django Multi-Table inheritance and model creation


Unfortunately model “promotion” like this is problematic. The proper way is to create a new Restaurant object by copying the fields from Place. You have to do this by iterating through Place._meta.get_fields_with_model() and seeing which model the fields belong to. I can’t give you the exact code for that, but if you can live with GPLed code then it’s in transifex.txcommon.models since revision bcd274ce7815.


I think you should add a foreign key to Restaurant like so:

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(models.Model):
    place = models.ForeignKey(Place)
    serves_hot_dogs = models.BooleanField()
    serves_pizza = models.BooleanField()

and then you can do:

>>> p = Place.objects.get(id=12)
>>> r = Restaurant(place=p)


I encountered the same problem. I think I have found a good solution:

I defined my Restaurant model by using three classes like this:

class RestaurantBase(models.Model):
    class Meta:
        abstract = True
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

class Restaurant(Place, RestaurantBase):

class RestaurantStandalone(RestaurantBase):
    class Meta:
        managed = False
        db_table = Restaurant._meta.db_table
    place_ptr = models.OneToOneRelationship(Place)

Now, if I have a place that I want to upgrade to a restaurant, I do the following:

p = Places.objects.get(id=3)
r = RestaurantStandalone()
r.place_ptr = p

now your place is a restaurant

r = Restaurant.objects.filter(place_ptr=p)


As I answered my own question here,

I ended up doing something along the lines of

p = Place.objects.get(name="Bob's Cafe")
    place_ptr = p.id,
    serves_hot_dogs = True,
    serves_pizza = False

Leave a comment