【问题标题】:Django Model Mixins: inherit from models.Model or from object?Django Model Mixins:继承自models.Model还是对象?
【发布时间】:2011-03-16 07:53:51
【问题描述】:

这是一个关于 Python Mixins 的问题,一般来说可能很有用。我只是使用 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)

我认为从对象继承是正确的方法。但是我在网上看到了第一个案例的例子......

编辑:我已将我的后续问题移至一个单独的问题:Django Abstract Models vs simple Python mixins vs Python ABCs

【问题讨论】:

    标签: python


    【解决方案1】:

    Django 在其模型类方面做了很多元魔法,所以不幸的是,Daniel Roseman 的回答中建议的通常的 mixins 方法——它们继承自 object——在 Django 世界中不能很好地工作.

    使用提供的示例构建 mixin 的正确方法是:

    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,所以您的实际模型应该不从它继承。如果这样做,这可能会触发一致的方法解析顺序异常。

    【讨论】:

    • 这将导致TypeError: Cannot create a consistent method resolution order (MRO)。请改用class MyModel(TaggingMixin):。见stackoverflow.com/q/29214888/1627479
    • 谢谢@Joren。编辑答案以反映这一点。
    • “混合”在这里是一个错误的术语。这只是一个抽象模型。您不能将其与models.Model 或其他抽象模型“混合”
    • @DavidAvsajanishvili 但是为什么呢?我刚刚测试了class Comment(ModelTimestampsMixin, models.Model),它就像一个魅力。我错过了什么吗?
    • 对不起@serghei,是的,你是对的。您的示例 class A(B, C) 使用的是 mixin 样式,但答案中的示例未使用 Mixin 样式,因为 mixin 被用作基类。通常,mixin 只会添加部分功能。你说得对,示例中的TaggingMixin 可以用作class NewClass(TaggingMixin, BaseClass) 形式的mixin。我认为这种说法并不完全正确:unfortunately the usual approach to mixins [...] does not work well in the Django universe。它们确实有效,但需要从 Model 继承。
    【解决方案2】:

    我建议它继承自 object。这样您就可以确保它只提供您实际明确定义的那些方法和属性。

    此外,在定义具体类时,您应该始终确保将 mixin 类放在首位。 Python 的解析规则意味着在类声明中按照它们的定义顺序搜索超类,当找到匹配的属性时解析停止。因此,如果您的 mixin 定义了一个也由主超类定义的方法,那么您的 mixin 方法将不会被找到。

    【讨论】:

    • 如果你的 mixin 类不继承自 models.Model(或者更具体地说,没有所需的 __metaclass__),则添加字段的元类魔法不起作用。
    • 从对象继承对我不起作用。见:stackoverflow.com/questions/17343867/…
    • 继承对象不是 django 的好方法。因为 django makemigrations 无法识别它。迁移文件不包含那些文件。
    • 添加一个带模板的小例子就好了。
    【解决方案3】:

    这看起来像是 abstract model 的工作。

    编辑:

    这些本身不是 mixin。或者更确切地说,他们不需要。您可以直接从抽象模型派生。

    【讨论】:

    • 呃,是的,你是对的,这是一个抽象模型的工作,实际上我只是在代码中忘记了它们:s 我已经添加了它,但现在我开始平衡了对我自己的问题更加困惑......
    【解决方案4】:

    当您从普通 Python 对象继承时,South 不会创建迁移,因此您不能使用这种方法

    【讨论】:

    • 与南迁无关。
    • 我的意思是这种方法不能很好地适应南方,这对我来说是个大问题
    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多