Swan
Swan

Reputation: 92

What is the proper way to retrieve all class definitions that contain a specific mixin?

I'm working on a django application, and I want to create a mixin that will always be applied to model definitions. The functionality added by the mixin isn't important for the question.

However, I need to be able to retrieve a list of all the class definitions that inherit from this mixin. These classes can be in different apps within the django project.

Possible answers I've found so far are:

How to find all the subclasses of a class given its name?

How to auto register a class when it's defined

I'm mostly wondering what the best method would be to accomplish this goal.

Upvotes: 2

Views: 395

Answers (1)

tim-mccurrach
tim-mccurrach

Reputation: 6815

Typically the way you would get a list of all the classes that inherit a particular class would be by registering the classes with a meta-class (as is explained in one of the questions you have linked). Django models however use their own meta class to achieve a lot of what they do automatically. I wouldn't recommend adding another meta-class into the mix - things could go wrong here!!

Fortunately however, django has something called the content-types framework which is essentially a registry of all of your models in a particular project.

To get a list of all of your models you can do this:

from django.contrib.contenttypes.models import ContentType

content_types = ContentType.objects.all()

This won't get the actual models, but rather a queryset of ContentType instances. To then get the model classes from this you can do

models = [x.model_class() for x in content_types]

So we now have a list of models. Then we can just filter the list down to those models which inherit your mixin:

models_with_mixin = [x for x in models if issubclass(x, MyMixin)]

We can simplify all of the above into the following:

from django.contrib.contenttypes.models import ContentType

models_with_mixin = [
    x.model_class()
    for x in ContentType.objects.all()
    if issubclass(x.model_class(), MyMixin)
]

Upvotes: 1

Related Questions