我问自己在mixin中覆盖save方法是否有意义。
在我的项目中,我有充分理由在多个模型中覆盖save方法。
首先,我必须创建一个继承自models.Model
的自定义模型类。
无论从语义上讲,我所做的是为一个类赋予一个角色(而不是自己定义一个对象),这就是为什么我认为写一个mixin更好。
另一个原因是因为我们可能在不久的将来使用多重继承。
另一方面,这一行在覆盖保存方法中:
super(MyMixin, self).save(*args, **kwargs)
不会产生敏感,因为它只能与django.db.models.Model类一起使用。
class MyMixin(object):
def save(self, *args, **kwargs):
...
super(MyMixin, self).save(*args, **kwargs)
...
你能帮我决定最好的选择吗? (Mixin或自定义模型)
答案 0 :(得分:8)
mro(方法解析顺序)的工作方式,两种方法都完全有效。抽象模型的情况非常简单:你有一个单独的继承链,每个对super的调用都会在链中的下一个类上调用。所以如果你有:
class MyBaseModel(models.Model):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
class MyModel(MyBaseModel):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
MyModel
中的来电将传播到MyBaseModel
,MyBaseModel
中的来电将传播到models.Model
。
使用多重继承,继承链略有不同。继承链中的第一个类是定义的第一个基类。因此,如果您有class MyModel(MyMixin, models.Model)
,MyMixin
将成为第一个向上的班级。接下来,在super()
(带有MyMixin
实例)中调用MyModel
时,它将查找MyMixin
类的兄弟。这意味着要调用的下一个方法是save
上的models.Model
方法。
考虑到这一点,使用mixin来覆盖保存方法是完全可以的。在这两种情况下,首先调用MyModel
save方法,然后调用mixin / abstract模型的save方法,最后调用models.Model
save方法。
注意:强>
这是在此特定情况下有效的方法解析顺序的简化说明。用于确定顺序的实际算法是C3线性化算法。可以找到完整的解释here。