[Answered ]-Django GenericForeignKey limit to ContentTypes that inherit from a particular abstract model

1👍

Refrecing to a model during import time is no longer supported from django 1.7. You should use your models after all application are loaded. So you should either Staticly pass a list to your limit_choices_to or Use Q object like this:

limit_choices_to=models.Q(app_label = 'app', model = 'a') | models.Q(app_label = 'app', model = 'b')

Also you can limit what shows to user in form level

1👍

So I arrived here looking for the answer. Based on Mehran’s post, I developed the below approach which is similar to yours. Instead the limit_choice_to calls a method that returns a runtime created Q object.

Below is the part that is similar to your get_subclasses.

def get_subclasses(cls, *args, **kwargs):
    for app_config in apps.get_app_configs():
        for app_model in app_config.get_models():
            model_classes = [c.__name__ for c in inspect.getmro(app_model)]
            if cls.__name__ in model_classes:
                yield app_model

This creates the Q filter(s) for us (in my implementation, this is just a plain old method not attached to any class, but I suppose it could be):

def get_content_choices():
    query_filter = None

    for cls in Solution.get_subclasses():

        app_label, model = cls._meta.label_lower.split('.')
        current_filter = models.Q(app_label=app_label, model=model)

        if query_filter is None:
            query_filter = current_filter
        else:
            query_filter |= current_filter

    return query_filter

And finally, in our model:

class ProblemSolutionMapping(models.Model):
    ...
    content_type = models.ForeignKey(ContentType, limit_choices_to=get_content_choices())
    ...

Leave a comment