views:

35

answers:

2

Let's say I have a class called Fruit with child classes of the different kinds of Fruit with their own specific attributes, and I want to collect them in a FruitBasket:

class Fruit(models.Model):
    type = models.CharField(max_length=120,default='banana',choices=FRUIT_TYPES)
    ...

class Banana(Fruit):
    """banana (fruit type)"""
    length = models.IntegerField(blank=True, null=True)     ...

class Orange(Fruit):
    """orange (fruit type)"""
    diameter = models.IntegerField(blank=True, null=True)     ...

class FruitBasket(models.Model):
    fruits = models.ManyToManyField(Fruit)     ...

The problem I seem to be having is when I retrieve and inspect the Fruits in a FruitBasket, I only retrieve the Fruit base class and can't get at the Fruit child class attributes.

I think I understand what is happening--when the array is retrieved from the database, the only fields that are retrieved are the Fruit base class fields. But is there some way to get the child class attributes as well without multiple expensive database transactions? (For example, I could get the array, then retrieve the child Fruit classes by the id of each array element).

thanks in advance, Chuck

A: 

http://docs.djangoproject.com/en/dev/topics/db/models/#id7

The trick is that since it is a reference back to the Fruit class, you may not know which type of fruit it is. But assuming you do, then you just access an instance of the subclass via the automatic OneToOne relation: mybasket.fruits.all()[0].orange

teepark
Thanks! One thing though--the access is via: mybasket.fruits.all()[0].orange, I think...
you're totally right. fixed.
teepark
A: 

We solved this problem by adding a Generic Foreign Key to the parent class. When the save() is done, the class/id of the child is saved in the parent. Then when you have an array of parent objects (Fruits in this case) you can say parent.child and you have the full child-class object. This question has come up a number of times and I'm a little surprised that it isn't at least on the wish list for ORM features. (or maybe it is and I just missed it....)

Peter Rowell