ConorMoore
ConorMoore

Reputation: 1

MPTT Multiple Inheritance Fails after Upgrade From Django3.0 to Django3.1

I've been having little luck trying to solve this issue so far. But in order to fix some vulnerable packages I'm upgrading a Django application from 2.8 -> 3.2, going from 2.8 -> 3.0 worked without issue, but as I go to 3.1 I begin failing in the collectstatic step due with the unhelpful django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. Here is the definition for the affected class

class OrganizationHierarchyNode(
        MPTTModel,
        WithAPI,
        ModelWithSoftDelete,
        metaclass=classmaker()):
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
    parent = TreeForeignKey(
        'self',
        null=True,
        blank=True,
        related_name='children',
        db_index=True, on_delete=models.CASCADE)
    hierarchy_level_map = models.ForeignKey(
        'HierarchyLevelMap', null=True, blank=True, on_delete=models.SET_NULL)
    root = None
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='created_by',
                                   on_delete=models.CASCADE)
    modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='modified_by',
                                    on_delete=models.CASCADE)

    hierarchy_scope = models.CharField(max_length=200, null=True, editable=False, blank=True)

I'm using django-mptt v0.16.0 and python v3.9.

I can see in the logs that it's failing when it calls that classmaker() function

def classmaker(left_metas=(), right_metas=()):
    def make_class(name, bases, adict):
        print(f"ttyxl Name: {name}")
        print(f"ttyxl Bases: {bases}")
        print(f"ttyxl Adict: {adict}")
        metaclass = get_noconflict_metaclass(bases, left_metas, right_metas)
        print(f"ttyxl Metaclass: {metaclass(name, bases, adict)}")
        return metaclass(name, bases, adict)

    return make_class

It will print out once for the base class

ttyxl Name: OrganizationHierarchyNode
ttyxl Bases: (<class 'mptt.models.MPTTModel'>, <class 'mgmt.api.models.with_api.WithAPI'>, <class 'mgmt.models.base.ModelWithSoftDelete'>)

Then immediatly following that it will output

ttyxl Name: _MPTTModelBaseWithAPIMeta
ttyxl Bases: (<class 'mptt.models.MPTTModelBase'>, <class 'entity_mgmt.api.models.with_api_meta.WithAPIMeta'>)
ttyxl Adict: {}
ttyxl Metaclass: <class 'mgmt.nonconflict._MPTTModelBaseWithAPIMeta'>

Before crashing with the above error.

I feel like there's likely been some change with how Django orders the loading of models, but I've had no luck in finding anything. Either that or the process is failing in some unknown way.

Edit: This only occurs for the metaclasses that import MPTTModel, the other classes that are similar have no such issue.

Upvotes: 0

Views: 44

Answers (0)

Related Questions