Django Model Mixins:继承自models.Model还是来自对象?

hop*_*pla 67 python

这是一个关于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)
Run Code Online (Sandbox Code Playgroud)

或这个:

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

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

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

编辑:我已将我的后续问题转移到一个单独的问题:Django抽象模型与简单Python混合与Python ABCs

jsd*_*ton 70

当谈到模型类时,Django会做很多元魔术,所以不幸的是,Daniel Roseman的回答中提到的mixins的常用方法 - 他们继承的地方object- 在Django世界中并不奏效.

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

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

    class Meta:
        abstract = True

class MyModel(TaggingMixin):
    title = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

重点是:

  • Mixins继承自model.Model但被配置为抽象类.
  • 由于混入继承model.Model,您的实际模型应该没有继承它.如果这样做,这可能会触发一致的方法解析顺序异常.

  • "Mixin"在这里是一个错误的术语.这只是一个抽象的模型.你不能将它与`models.Model`或其他抽象模型"混合" (12认同)
  • @DavidAvsajanishvili 但为什么呢?我刚刚测试了“class Comment(ModelTimestampsMixin, models.Model)”,它的工作方式就像一个魅力。我错过了什么? (3认同)
  • 抱歉@serghei,是的,你是对的。您的示例“class A(B, C)”使用 mixin 样式,但答案中的示例未使用 Mixin 样式,因为 mixin 被用作基类。通常,mixin 只会添加部分功能。你说得对,示例中的“TaggingMixin”可以用作“class NewClass(TaggingMixin, BaseClass)”形式的混合。我认为这个说法并不完全正确:“不幸的是,mixin 的常用方法 [...] 在 Django 世界中效果不佳”。它们确实有效,但需要从 Model 继承。 (2认同)

Dan*_*man 16

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

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

  • 如果你的mixin类不继承自`models.Model`(或更具体地说,没有所需的`__metaclass__`),那么添加字段的元类魔法不起作用. (11认同)
  • 从对象继承并不适合我.请参阅:http://stackoverflow.com/questions/17343867/does-south-handle-model-mixins (2认同)
  • 继承对象不是django的好方法.因为django makemigrations无法识别它.迁移文件不包含那些归档文件. (2认同)

Ign*_*ams 6

这看起来像抽象模型的工作.

编辑:

那些不是mixins本身.或者说,他们不需要.您可以直接从抽象模型派生.

  • 呃,是的,你是对的,这是抽象模型的工作,事实上我只是在代码中忘记了它们:我已经添加了它,但现在我开始对自己的问题感到更加困惑.. 。 (2认同)