Reputation: 2922
I have a django abstract class:
class AbstractModel(models.Model):
date_added = models.DateField(auto_now_add=True)
class Meta:
abstract = True
I want my concrete classes (Django Models) to subclass this abstract class, but I also want to make sure that all my concrete classes always implement very specific methods using abc
.
I tried doing this:
class AbstractBaseClass(AbstractModel, metaclass=abc.ABCMeta):
@abstractmethod
def important_method(self):
pass
class MyDjangoModel(AbstractBaseClass):
...
And I tried:
class AbstractBaseClass(ABC):
@abstractmethod
def important_method(self):
pass
class MyDjangoModel(AbstractModel, AbstractBaseClass):
Neither worked. They both say:
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Is there a way to do this, or is this impossible?
Upvotes: 3
Views: 598
Reputation: 11346
You're pretty close to the right solution, see the example:
import abc
from django.db import models
class AbstractModelMeta(abc.ABCMeta, type(models.Model)):
"""AbstractModelMeta used as a metaclass"""
class AbstractBaseClass(models.Model, metaclass=AbstractModelMeta):
date_added = models.DateField(auto_now_add=True)
class Meta:
abstract = True
@abc.abstractmethod
def important_method(self):
pass
class MyDjangoModel(AbstractBaseClass):
first_name = models.CharField(max_length=10)
You'll get an error if abstract methods aren't implemented as expected:
>>> from main.models import MyDjangoModel
>>> m = MyDjangoModel()
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: Can't instantiate abstract class MyDjangoModel with abstract methods important_method
Upvotes: 5