views:

41

answers:

1

I have two models than inherited from the same abstract base class.

I would expect to be able to get all instances from classes that are children of the base class with something like AbstractClass.objects.all()

Of course I could join queries on all children but that's awful and it stops working if I add new children class.

Is this possible with Django ORM ? What would be the elegant solution ?

+1  A: 

I have used django's other inheritance methods because I hit the same problem you are running into. I'm not sure if there is an elegant solution. Ultimately, you need several queries done on the DB and for the results to be merged together. I can't picture the ORM supporting that.

Here is my usual hackish approach for this situation:

class NotQuiteAbstractBaseClass(models.Model):
    def get_specific_subclass(self):
        if self.model1:
            return self.model1
        elif self.model2:
            return self.model2
        else:
            raise RuntimeError("Unknown subclass")

class Model1(NotQuiteAbstractBaseClass):
    def whoami(self):
        return "I am a model1"

class Model2(NotQuiteAbstractBaseClass):
    def whoami(self):
        return "I am a model2"

Then, you can query the entire list like this:

for obj in NotQuiteAbstractBaseClass.objects.iterator():
    obj = obj.get_specific_subclass()
    print obj.whoami()
Gattster
I'll wait a little hoping for better but so far it seems that multiple queries is the way to go. Do you have a clever way to deal with adding new child classes or do you have to update the queries if you add more child classes ?I have quite a bit of OOP experience, but only started Python 80 hours ago, so I am very limited. I am sure there as to be a way to make it dynamic with callable functions.
PhilGo20
I too will wait to see if we get a better answer. This has been a long standing question of mine. I use the standard django inheritance and query for the abstract base class. The problem here is that you get instances of the base class, not the specific subclass that you want. To workaround this, I register each of the subclasses in an array somewhere. Then I put a `get_specific_subclass()` method on my base class. This basically loops over the array and tests if we can be cast as that type. I'd love to hear a better solution. My method gets the job done, but it doesn't feel "right".
Gattster
"I use the standard django inheritance and query for the abstract base class." What does that mean ? Can you give an example of your query on the ABC ? Haven't managed to do that.
PhilGo20
I updated my answer to show you what I mean. It's not exactly what you are working for but it is a solution that I've used a few times with good luck.
Gattster
I don't want to deal with a non-astract class so i'll join queries. Not very dynamic as I will have to update the code to add new child class but will do the trick for now.
PhilGo20
Pick your poison. Good luck and please post an update if you get a better solution.
Gattster