Модель Django, которая подклассов abc, дает конфликт метакласса - PullRequest
12 голосов
/ 04 января 2012

У меня есть следующая модель и абстрактный базовый класс

import abc
from django.db import models


class AbstractBase():
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def my_method(self):
        return


class MyModel(models.Model, AbstractBase):
    @abc.abstractmethod
    def my_method(self):
        return 1

Но я получаю следующую ошибку.

конфликт метакласса: метакласс производного класса должен быть(не строгий) подкласс метаклассов всех его баз

Я думаю, что проблема здесь в том (как здесь описано http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/), что два базовых класса имеют два разных метакласса, поэтому pythonне могу решить, какой метакласс использовать для дочернего объекта.

Чтобы решить эту проблему, я удалил множественное наследование и использую следующий метод регистра для регистрации дочернего класса

abc.register(Child)

Но мне это не очень понравилосьподход, так как это выглядит как исправление обезьян.

Есть ли другой способ решения этой проблемы?

Я пытаюсь явно назначить метакласс Model для Child, но это не сработало. Я не ищуспособ решить это путем написания кода. Я думаю, что это должно быть решено путем изменения структуры моего класса.

1 Ответ

2 голосов
/ 04 января 2012

Помимо создания нового метакласса, который наследует от ABCMeta и ModelBase, или создания ABCMeta наследования от ModelBase, , вы мало что можете сделать.

Однако, возможно, подойдет другой шаблон регистрации? Может быть, что-то вроде contrib.admin.autodiscover? Или декоратор класса? Или цикл в нижней части файла .py, который вызывает register для соответствующих классов (например, for var in globals().values(): if isinstance(var, type) and issubclass(var, AbastractBase): register(var))?

Редактировать : Д'Ох. Я предположил, что ABCMeta был примером, а не ABCMeta. Это то, что я получаю за просмотр StackOverflow на слишком мало сна.

...