Могу ли я использовать ABC и Django Abstract classes вместе в Python?
У меня есть абстрактный класс django:
class AbstractModel(models.Model):
date_added = models.DateField(auto_now_add=True)
class Meta:
abstract = True
Я хочу, чтобы мои конкретные классы (Django Models) подклассифицировали этот абстрактный класс, но я также хочу убедиться, что все мои конкретные классы всегда реализуют очень специфические методы, используя abc
.
Я попробовал сделать следующее:
class AbstractBaseClass(AbstractModel, metaclass=abc.ABCMeta):
@abstractmethod
def important_method(self):
pass
class MyDjangoModel(AbstractBaseClass):
...
И я попробовал:
class AbstractBaseClass(ABC):
@abstractmethod
def important_method(self):
pass
class MyDjangoModel(AbstractModel, AbstractBaseClass):
Ни то, ни другое не сработало. Они оба говорят:
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Есть ли способ сделать это, или это невозможно?
Вы довольно близки к правильному решению, смотрите пример:
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)
Вы получите ошибку, если абстрактные методы реализованы не так, как ожидалось:
>>> 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