Django模型混入:继承自models.Model还是object?
这是一个关于Python中Mixin的提问,可能对大家都有帮助。我这里用Django模型作为例子,因为这是我最熟悉的用法。
Mixin应该继承它要混入的类,还是直接继承'object'呢?
通过代码示例,哪种方式更正确或者更好,或者说根据你想要实现的目标,哪种更合适呢?
这种方式:
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)
我觉得继承'object'是正确的做法。但是我在网上看到很多例子都是第一种情况……
编辑:我把我的后续问题移到了一个单独的问题上: Django抽象模型 vs 简单Python mixins vs Python ABCs
4 个回答
12
14
我建议让它继承自 object
。这样可以确保它只提供你明确定义的方法和属性。
另外,在定义你的具体类时,应该始终把混入类放在 最前面。因为Python的查找规则是按你在类声明中定义的顺序来查找父类的,一旦找到匹配的属性就会停止查找。所以如果你的混入类定义了一个方法,而这个方法在主父类中也有定义,那么你的混入类的方法就找不到了。
104
Django在处理模型类时会做很多“魔法”,所以通常的混入类(mixins)写法,比如Daniel Roseman提到的那种从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
继承的,所以你的实际模型类不应该从它继承。如果你这样做,可能会引发一种叫做“方法解析顺序异常”的错误。