Django模型混合:继承自模型。从对象模型或?

时间:2022-09-24 23:41:53

This is a question about Python Mixins that might be useful in general. I'm just using Django models as that is the use-case I'm most familiar with.

这是一个关于Python mixin的问题,它可能在一般情况下是有用的。我只是使用Django模型,因为这是我最熟悉的用例。

Should a mixin inherit from the class it is designed to mix-in with or from 'object'?

mixin是否应该继承其设计为与'object'混合的类?

Examples by code, what is more correct or better, or better depending on what you want to achieve?

代码中的例子,什么更正确或更好,或者更好,取决于您想要实现什么?

This

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

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

Or this:

或:

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

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

I think inheriting from object is the right way. But I'm seeing examples of the first case all over the net...

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

EDIT: I've moved my follow up question to a separate question: Django Abstract Models vs simple Python mixins vs Python ABCs

编辑:我已经把我的后续问题转移到另一个问题:Django抽象模型vs简单的Python mixin vs Python ABCs

4 个解决方案

#1


52  

Django does a lot of meta magic when it comes to its model classes, so unfortunately the usual approach to mixins as suggested in Daniel Roseman's answer -- where they inherit from object -- does not work well in the Django universe.

Django在它的模型类中使用了很多元魔法,所以不幸的是,Daniel Roseman的答案——从对象继承的——通常的方法在Django的宇宙中并不适用。

The correct way to structure your mixins, using the example provided, would be:

使用所提供的示例构造混合器的正确方法是:

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

    class Meta:
        abstract = True

class MyModel(TaggingMixin):
    title = models.CharField(max_length=100)

Important points here being:

重要的点是:

  • Mixins inherit from model.Model but are configured as an abstract class.
  • mixin继承模型。模型,但被配置为一个抽象类。
  • Because mixins inherit from model.Model, your actual model should not inherit from it. If you do, this might trigger a consistent method resolution order exception.
  • 因为mixin继承自model。模型,您的实际模型不应该继承它。如果这样做,可能会触发一致的方法解析顺序异常。

#2


13  

I would recommend that it inherits from object. That way you can ensure that it only provides those methods and attributes you actually define explicitly.

我建议它从对象继承。这样,您可以确保它只提供您实际显式定义的方法和属性。

Also, you should always ensure that you put the mixin class first when defining your concrete class. Python's resolution rules mean that the superclasses are searched in order of their definition in the class declaration, and resolution stops when a matching attribute is found. So if your mixin defines a method that is also defined by the main superclass, your mixin method won't be found.

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

#3


6  

This looks like a job for an abstract model.

这看起来像是一个抽象模型的工作。

EDIT:

编辑:

Those are not mixins per se. Or rather, they do not need to be. You can derive from an abstract model directly.

它们本身不是混合物。或者更确切地说,他们不需要这么做。您可以直接从抽象模型派生。

#4


3  

When you inherits from plain Python object South doesn't create a migration so you can't use this approach

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

#1


52  

Django does a lot of meta magic when it comes to its model classes, so unfortunately the usual approach to mixins as suggested in Daniel Roseman's answer -- where they inherit from object -- does not work well in the Django universe.

Django在它的模型类中使用了很多元魔法,所以不幸的是,Daniel Roseman的答案——从对象继承的——通常的方法在Django的宇宙中并不适用。

The correct way to structure your mixins, using the example provided, would be:

使用所提供的示例构造混合器的正确方法是:

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

    class Meta:
        abstract = True

class MyModel(TaggingMixin):
    title = models.CharField(max_length=100)

Important points here being:

重要的点是:

  • Mixins inherit from model.Model but are configured as an abstract class.
  • mixin继承模型。模型,但被配置为一个抽象类。
  • Because mixins inherit from model.Model, your actual model should not inherit from it. If you do, this might trigger a consistent method resolution order exception.
  • 因为mixin继承自model。模型,您的实际模型不应该继承它。如果这样做,可能会触发一致的方法解析顺序异常。

#2


13  

I would recommend that it inherits from object. That way you can ensure that it only provides those methods and attributes you actually define explicitly.

我建议它从对象继承。这样,您可以确保它只提供您实际显式定义的方法和属性。

Also, you should always ensure that you put the mixin class first when defining your concrete class. Python's resolution rules mean that the superclasses are searched in order of their definition in the class declaration, and resolution stops when a matching attribute is found. So if your mixin defines a method that is also defined by the main superclass, your mixin method won't be found.

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

#3


6  

This looks like a job for an abstract model.

这看起来像是一个抽象模型的工作。

EDIT:

编辑:

Those are not mixins per se. Or rather, they do not need to be. You can derive from an abstract model directly.

它们本身不是混合物。或者更确切地说,他们不需要这么做。您可以直接从抽象模型派生。

#4


3  

When you inherits from plain Python object South doesn't create a migration so you can't use this approach

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