Могу ли я использовать 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
Вернуться на верх