In Django <=2.2, it is possible for models to define a custom metaclass (as a subclass of models.base.ModelBase
) and access the attribute dict of the class being defined:
from django.db import models
class PageBase(models.base.ModelBase):
def __init__(cls, name, bases, dct):
super(PageBase, cls).__init__(name, bases, dct)
if 'magic' in dct:
print("enabling magic on %s" % (name))
class Page(models.Model, metaclass=PageBase):
magic = True
title = models.CharField(max_length=255)
As of commit a68ea231012434b522ce45c513d84add516afa60, this fails because all attributes without a contribute_to_class
method are popped from the dict in ModelBase.__new__
.
(This pattern is used by Wagtail's Page model https://github.com/wagtail/wagtail/blob/3e1e67021e0a20783ed59e17b43e3c481897fce3/wagtail/core/models.py#L190 , so this is causing various failures against django stable/2.2.x.)
PR: https://github.com/django/django/pull/11085