moenad moenad - 2 months ago 15
Python Question

Django access to subclasses items from abstract class

class Animal(models.Model):
....
class Meta:
abstract = True

class Cat(models.Model, Animal):
...

class Dog(models.Model, Animal):
....


I want to be able to return all instances of querysets of all the subclasses of Animal. Lets say I have a function called
allData
which returns an array/list of all the subclasses querysets.

For example:

x = animal.allData()[0] # should return the first element in the array.


I don't mind how we do this, using modules like
django-model-utils
or not. I just want to be able to return all the subclasses querysets.

Answer

This is not possible in one query. You have two options, one use to use django-model-utils or you can use django_polymorphic.

Polymorphic is better suited to your task, however django-model-utils is made by a very prominent member of the django community and as such has a lot of good support.

If I had to choose, I'd choose django-model-utilts since its made by a member of the django team, and thus will be supported. Polymorphic is supported by divio, which is a private company that heavily uses django based in Switzerland.

As for how to select Sub-classes. You need to do two things using django-model-utils. Firstly, you need to change the objects variable in your model to InheritanceManager() like so (adapted from docs):

from model_utils.managers import InheritanceManager

class Place(models.Model):
    # ...
    objects = InheritanceManager()

class Restaurant(Place):
    # ...

class Bar(Place):
    # ...

nearby_places = Place.objects.filter(location='here').select_subclasses()
for place in nearby_places:
    # "place" will automatically be an instance of Place, Restaurant, or Bar

The code above will return all Bars and Restaurants because it uses the select_subclasses.