Django Model Mixins: наследовать от моделей. Моделя или из объекта?
Это вопрос о Python Mixins, который может быть полезен вообще. Я просто использую модели Django, так как это наиболее подходящий вариант использования.
Должен ли mixin наследовать от класса, который он предназначен для смешивания с или из объекта?
Примеры по коду, правильнее или лучше, или лучше, в зависимости от того, чего вы хотите достичь?
Это
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 Abstract Models против простых Python mixins vs Python ABC
Ответы
Ответ 1
Django делает много мета-магии, когда дело доходит до его модельных классов, поэтому, к сожалению, обычный подход к mixins, предложенный в ответе Даниэля Роуземана, где они наследуются от object
, не работает хорошо во вселенной Django.
Правильный способ структурирования ваших микшинов с использованием приведенного примера будет:
class TaggingMixin(models.Model):
tag = models.ForeignKey(Tag)
class Meta:
abstract = True
class MyModel(TaggingMixin):
title = models.CharField(max_length=100)
Важные моменты здесь:
- Mixins наследуют от
model.Model
, но настроены как абстрактный класс.
- Поскольку mixins наследуют от
model.Model
, ваша фактическая модель не должна наследовать от нее. Если вы это сделаете, это может вызвать исключение порядка согласования метода.
Ответ 2
Я бы порекомендовал, чтобы он наследовал от object
. Таким образом, вы можете гарантировать, что он предоставляет только те методы и атрибуты, которые вы действительно определяете явно.
Кроме того, вы всегда должны убедиться, что сначала ставите класс mixin при определении своего конкретного класса. Правила разрешения Python означают, что суперклассы выполняются в порядке их определения в объявлении класса, и разрешение останавливается, когда найден соответствующий атрибут. Поэтому, если ваш mixin определяет метод, который также определяется основным суперклассом, ваш метод mixin не будет найден.
Ответ 3
Это выглядит как работа для абстрактной модели .
EDIT:
Это не микшины как таковые. Вернее, им не обязательно быть. Вы можете непосредственно получить абстрактную модель.
Ответ 4
Когда вы наследуете от простого объекта Python, юг не создает миграцию, поэтому вы не можете использовать этот подход