Django Model Mixins: наследовать от models.Model или от объекта? - PullRequest
61 голосов
/ 15 июля 2010

Это вопрос о Python Mixins, который может быть полезен в целом.Я просто использую модели Django, так как это тот случай использования, с которым я больше всего знаком.

Должен ли миксин наследовать от класса, для которого он предназначен для встраивания в объект или из него?

Примеры по коду: что правильнее или лучше или лучше в зависимости от того, чего вы хотите достичь?

Это

class TaggingMixin(models.Model):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

Или это:

class TaggingMixin(object):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

Я думаю, что наследование от объекта - это правильный путь.Но я вижу примеры первого случая по всей сети ...

РЕДАКТИРОВАТЬ: Я перенес свой следующий вопрос на отдельный вопрос: Абстрактные модели Djangoпротив простых миксов Python против азбуки Python

Ответы [ 4 ]

65 голосов
/ 13 сентября 2014

Django делает много мета-магии, когда дело доходит до своих модельных классов, поэтому, к сожалению, обычный подход к миксинам, предложенный в ответе Дэниэла Роузмана - где они наследуются от object - не работает хорошо во вселенной Django .

Правильный способ структурировать ваши миксины, используя приведенный пример, будет:

class TaggingMixin(models.Model):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(TaggingMixin):
    title = models.CharField(max_length=100)

Важными моментами здесь являются:

  • Миксины наследуются от model.Model, но настроены как абстрактный класс.
  • Поскольку миксины наследуются от model.Model, ваша фактическая модель должна не наследовать от нее. В противном случае это может вызвать согласованное исключение порядка разрешения методов.
15 голосов
/ 15 июля 2010

Я бы порекомендовал, чтобы он наследовал от object.Таким образом, вы можете быть уверены, что он предоставляет только те методы и атрибуты, которые вы на самом деле определяете явно.

Кроме того, вы всегда должны всегда указывать класс mixin first при определении конкретного класса.Правила разрешения Python означают, что суперклассы ищутся в порядке их определения в объявлении класса, и разрешение останавливается, когда найден соответствующий атрибут.Поэтому, если ваш миксин определяет метод, который также определен главным суперклассом, ваш миксин-метод не будет найден.

6 голосов
/ 15 июля 2010

Это похоже на работу для абстрактной модели .

РЕДАКТИРОВАТЬ:

Это не миксины как таковые.Вернее, им не нужно быть.Вы можете напрямую получить абстрактную модель.

3 голосов
/ 09 июля 2013

Когда вы наследуете от простого объекта Python, South не создает миграцию, поэтому вы не можете использовать этот подход

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...